﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-xiaoguozi's Blog-随笔分类-SQL</title><link>http://www.cppblog.com/guojingjia2006/category/11422.html</link><description>Pay it forword - 我并不觉的自豪，我所尝试的事情都失败了······习惯原本生活的人不容易改变，就算现状很糟，他们也很难改变，在过程中，他们还是放弃了······他们一放弃，大家就都是输家······让爱传出去，很困难，也无法预料，人们需要更细心的观察别人，要随时注意才能保护别人，因为他们未必知道自己要什么·····</description><language>zh-cn</language><lastBuildDate>Fri, 12 Jul 2013 09:58:15 GMT</lastBuildDate><pubDate>Fri, 12 Jul 2013 09:58:15 GMT</pubDate><ttl>60</ttl><item><title>mysql配置文件my.cnf详解[部分]</title><link>http://www.cppblog.com/guojingjia2006/archive/2013/07/12/201716.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 12 Jul 2013 01:16:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2013/07/12/201716.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/201716.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2013/07/12/201716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/201716.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/201716.html</trackback:ping><description><![CDATA[<div><table cellpadding="5" cellspacing="0" border="1"><tbody><tr><td><span style="font-size: 12px;">basedir = path</span></td> <td><span style="font-size: 12px;">使用给定目录作为根目录(安装目录)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">character-sets-dir = path</span></td> <td><span style="font-size: 12px;">给出存放着字符集的目录。</span></td> </tr> <tr> <td><span style="font-size: 12px;">datadir = path</span></td> <td><span style="font-size: 12px;">从给定目录读取数据库文件。</span></td> </tr> <tr> <td><span style="font-size: 12px;">pid-file = filename</span></td> <td><span style="font-size: 12px;">为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。</span></td> </tr> <tr> <td><span style="font-size: 12px;">socket = filename</span></td> <td><span style="font-size: 12px;">为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于 UNIX/Linux系统;  默认设置一般是/var/lib/mysql/mysql.sock文件)。在Windows环境下，如果MySQL客户与服务器是通过命名管道进行通信  的，&#8211;sock选项给出的将是该命名管道的名字(默认设置是MySQL)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">lower_case_table_name = 1/0</span></td> <td><span style="font-size: 12px;">新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：语言设置</strong></span></p> <table cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">character-sets-server = name</span></td> <td><span style="font-size: 12px;">新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容，这个字符集也可以用&#8211;default-character-set选项给出; 但这个选项已经显得有点过时了。</span></td> </tr> <tr> <td><span style="font-size: 12px;">collation-server = name</span></td> <td><span style="font-size: 12px;">新数据库或数据表的默认排序方式。</span></td> </tr> <tr> <td><span style="font-size: 12px;">lanuage = name</span></td> <td><span style="font-size: 12px;">用指定的语言显示出错信息。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：通信、网络、信息安全</strong></span></p> <table cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">enable-named-pipes</span></td> <td><span style="font-size: 12px;">允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL，但可以用&#8211;socket选项来改变。</span></td> </tr> <tr> <td><span style="font-size: 12px;">local-infile [=0]</span></td> <td><span style="font-size: 12px;">允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。</span></td> </tr> <tr> <td><span style="font-size: 12px;">myisam-recover [=opt1, opt2, ...]</span></td> <td><span style="font-size: 12px;">在启动时自动修复所有受损的MyISAM数据表。这个选项的可取值有4种:DEFAULT、BACKUP、QUICK和FORCE; 它们与myisamchk程序的同名选项作用相同。</span></td> </tr> <tr> <td><span style="font-size: 12px;">old-passwords</span></td> <td><span style="font-size: 12px;">使用MySQL 3.23和4.0版本中的老算法来加密mysql数据库里的密码(默认使用MySQL 4.1版本开始引入的新加密算法)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">port = n</span></td> <td><span style="font-size: 12px;">为MySQL程序指定一个TCP/IP通信端口(通常是3306端口)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">safe-user-create</span></td> <td><span style="font-size: 12px;">只有在mysql.user数据库表上拥有INSERT权限的用户才能使用GRANT命令; 这是一种双保险机制(此用户还必须具备GRANT权限才能执行GRANT命令)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">shared-memory</span></td> <td><span style="font-size: 12px;">允许使用内存(shared memory)进行通信(仅适用于Windows)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">shared-memory-base-name = name</span></td> <td><span style="font-size: 12px;">给共享内存块起一个名字(默认的名字是MySQL)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">skip-grant-tables</span></td> <td><span style="font-size: 12px;">不使用mysql数据库里的信息来进行访问控制(警告:这将允许用户任何用户去修改任何数据库)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">skip-host-cache</span></td> <td><span style="font-size: 12px;">不使用高速缓存区来存放主机名和IP地址的对应关系。</span></td> </tr> <tr> <td><span style="font-size: 12px;">skip-name-resovle</span></td> <td><span style="font-size: 12px;">不把IP地址解析为主机名; 与访问控制(mysql.user数据表)有关的检查全部通过IP地址行进。</span></td> </tr> <tr> <td><span style="font-size: 12px;">skip-networking</span></td> <td><span style="font-size: 12px;">只允许通过一个套接字文件(Unix/Linux系统)或通过命名管道(Windows系统)进行本地连接，不允许ICP/IP连接; 这提高了安全性，但阻断了来自网络的外部连接和所有的Java客户程序(Java客户即使在本地连接里也使用TCP/IP)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">user = name</span></td> <td><span style="font-size: 12px;">mysqld程序在启动后将在给定UNIX/Linux账户下执行; mysqld必须从root账户启动才能在启动后切换到另一个账户下执行; mysqld_safe脚本将默认使用&#8211;user=mysql选项来启动mysqld程序。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：内存管理、优化、查询缓存区</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">bulk_insert_buffer_size = n</span></td> <td><span style="font-size: 12px;">为一次插入多条新记录的INSERT命令分配的缓存区长度(默认设置是8M)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">key_buffer_size = n</span></td> <td><span style="font-size: 12px;">用来存放索引区块的RMA值(默认设置是8M)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">join_buffer_size = n</span></td> <td><span style="font-size: 12px;">在参加JOIN操作的数据列没有索引时为JOIN操作分配的缓存区长度(默认设置是128K)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">max_heap_table_size = n</span></td> <td><span style="font-size: 12px;">HEAP数据表的最大长度(默认设置是16M); 超过这个长度的HEAP数据表将被存入一个临时文件而不是驻留在内存里。</span></td> </tr> <tr> <td><span style="font-size: 12px;">max_connections = n</span></td> <td><span style="font-size: 12px;">MySQL服务器同时处理的数据库连接的最大数量(默认设置是100)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">query_cache_limit = n</span></td> <td><span style="font-size: 12px;">允许临时存放在查询缓存区里的查询结果的最大长度(默认设置是1M)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">query_cache_size = n</span></td> <td><span style="font-size: 12px;">查询缓存区的最大长度(默认设置是0，不开辟查询缓存区)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">query_cache_type = 0/1/2</span></td> <td><span style="font-size: 12px;">查询缓存区的工作模式:0, 禁用查询缓存区; 1，启用查询缓存区(默认设置); 2，&#8221;按需分配&#8221;模式，只响应SELECT SQL_CACHE命令。</span></td> </tr> <tr> <td><span style="font-size: 12px;">read_buffer_size = n</span></td> <td><span style="font-size: 12px;">为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。</span></td> </tr> <tr> <td><span style="font-size: 12px;">read_rnd_buffer_size = n</span></td> <td><span style="font-size: 12px;">类似于read_buffer_size选项，但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">sore_buffer = n</span></td> <td><span style="font-size: 12px;">为排序操作分配的缓存区的长度(默认设置是2M); 如果这个缓存区太小，则必须创建一个临时文件来进行排序。</span></td> </tr> <tr> <td><span style="font-size: 12px;">table_cache = n</span></td> <td><span style="font-size: 12px;">同时打开的数据表的数量(默认设置是64)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">tmp_table_size = n</span></td> <td><span style="font-size: 12px;">临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：日志</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">log [= file]</span></td> <td><span style="font-size: 12px;">把所有的连接以及所有的SQL命令记入日志(通用查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname.log文件作为这种日志文件(hostname是服务器的主机名)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-slow-queries [= file]</span></td> <td><span style="font-size: 12px;">把执行用时超过long_query_time变量值的查询命令记入日志(慢查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname-slow.log文件作为这种日志文件(hostname是服务器主机 名)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">long_query_time = n</span></td> <td><span style="font-size: 12px;">慢查询的执行用时上限(默认设置是10s)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">long_queries_not_using_indexs</span></td> <td><span style="font-size: 12px;">把慢查询以及执行时没有使用索引的查询命令全都记入日志(其余同&#8211;log-slow-queries选项)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-bin [= filename]</span></td> <td><span style="font-size: 12px;">把对数据进行修改的所有SQL命令(也就是INSERT、UPDATE和 DELETE命令)以二进制格式记入日志(二进制变更日志，binary update  log)。这种日志的文件名是filename.n或默认的hostname.n，其中n是一个6位数字的整数(日志文件按顺序编号)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-bin-index = filename</span></td> <td><span style="font-size: 12px;">二进制日志功能的索引文件名。在默认情况下，这个索引文件与二进制日志文件的名字相同，但后缀名是.index而不是.nnnnnn。</span></td> </tr> <tr> <td><span style="font-size: 12px;">max_binlog_size = n</span></td> <td><span style="font-size: 12px;">二进制日志文件的最大长度(默认设置是1GB)。在前一个二进制日志文件里的信息量超过这个最大长度之前，MySQL服务器会自动提供一个新的二进制日志文件接续上。</span></td> </tr> <tr> <td><span style="font-size: 12px;">binlog-do-db = dbname</span></td> <td><span style="font-size: 12px;">只把给定数 据库里的变化情况记入二进制日志文件，其他数据库里的变化情况不记载。如果需要记载多个数据库里的变化情况，就必须在配置文件使用多个本选项来设置，每个数据库一行。</span></td> </tr> <tr> <td><span style="font-size: 12px;">binlog-ignore-db = dbname</span></td> <td><span style="font-size: 12px;">不把给定数据库里的变化情况记入二进制日志文件。</span></td> </tr> <tr> <td><span style="font-size: 12px;">sync_binlog = n</span></td> <td><span style="font-size: 12px;">每经过n次日志写操作就把日志文件写入硬盘一次(对日志信息进行一次同步)。n=1是最安全的做法，但效率最低。默认设置是n=0，意思是由操作系统来负责二进制日志文件的同步工作。</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-update [= file]</span></td> <td><span style="font-size: 12px;">记载出错情况的日志文件名(出错日志)。这种日志功能无法禁用。如果没有给出file参数，MySQL会使用hostname.err作为种日志文件的名字。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：镜像(主控镜像服务器)</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">server-id = n</span></td> <td><span style="font-size: 12px;">给服务器分配一个独一无二的ID编号; n的取值范围是1~2的32次方启用二进制日志功能。</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-bin = name</span></td> <td><span style="font-size: 12px;">启用二进制日志功能。这种日志的文件名是filename.n或默认的hostname.n，其中的n是一个6位数字的整数(日志文件顺序编号)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">binlog-do/ignore-db = dbname</span></td> <td><span style="font-size: 12px;">只把给定数据库里的变化情况记入二进制日志文件/不把给定的数据库里的变化记入二进制日志文件。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：镜像(从属镜像服务器)</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">server-id = n</span></td> <td><span style="font-size: 12px;">给服务器分配一个唯一的ID编号</span></td> </tr> <tr> <td><span style="font-size: 12px;">log-slave-updates</span></td> <td><span style="font-size: 12px;">启用从属服务器上的日志功能，使这台计算机可以用来构成一个镜像链(A-&gt;B-&gt;C)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-host = hostname</span></td> <td><span style="font-size: 12px;">主控服务器的主机名或IP地址。如果从属服务器上存在mater.info文件(镜像关系定义文件)，它将忽略此选项。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-user = replicusername</span></td> <td><span style="font-size: 12px;">从属服务器用来连接主控服务器的用户名。如果从属服务器上存在mater.info文件，它将忽略此选项。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-password = passwd</span></td> <td><span style="font-size: 12px;">从属服务器用来连接主控服务器的密码。如果从属服务器上存在mater.info文件，它将忽略此选项。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-port = n</span></td> <td><span style="font-size: 12px;">从属服务器用来连接主控服务器的TCP/IP端口(默认设置是3306端口)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-connect-retry = n</span></td> <td><span style="font-size: 12px;">如果与主控服务器的连接没有成功，则等待n秒(s)后再进行管理方式(默认设置是60s)。如果从属服务器存在mater.info文件，它将忽略此选项。</span></td> </tr> <tr> <td><span style="font-size: 12px;">master-ssl-xxx = xxx</span></td> <td><span style="font-size: 12px;">对主、从服务器之间的SSL通信进行配置。</span></td> </tr> <tr> <td><span style="font-size: 12px;">read-only = 0/1</span></td> <td><span style="font-size: 12px;">0: 允许从属服务器独立地执行SQL命令(默认设置); 1: 从属服务器只能执行来自主控服务器的SQL命令。</span></td> </tr> <tr> <td><span style="font-size: 12px;">read-log-purge = 0/1</span></td> <td><span style="font-size: 12px;">1: 把处理完的SQL命令立刻从中继日志文件里删除(默认设置); 0: 不把处理完的SQL命令立刻从中继日志文件里删除。</span></td> </tr> <tr> <td><span style="font-size: 12px;">replicate-do-table = dbname.tablename</span></td> <td><span style="font-size: 12px;">与&#8211;replicate-do-table选项的含义和用法相同，但数据库和数据库表名字里允许出现通配符&#8221;%&#8221; (例如: test%.%&#8211;对名字以&#8221;test&#8221;开头的所有数据库里的所以数据库表进行镜像处理)。</span> <p>&nbsp;</p> </td> </tr> <tr> <td><span style="font-size: 12px;">replicate-do-db = name</span></td> <td><span style="font-size: 12px;">只对这个数据库进行镜像处理。</span></td> </tr> <tr> <td><span style="font-size: 12px;">replicate-ignore-table = dbname.tablename</span></td> <td><span style="font-size: 12px;">不对这个数据表进行镜像处理。</span></td> </tr> <tr> <td><span style="font-size: 12px;">replicate-wild-ignore-table = dbn.tablen</span></td> <td><span style="font-size: 12px;">不对这些数据表进行镜像处理。</span></td> </tr> <tr> <td><span style="font-size: 12px;">replicate-ignore-db = dbname</span></td> <td><span style="font-size: 12px;">不对这个数据库进行镜像处理。</span></td> </tr> <tr> <td><span style="font-size: 12px;">replicate-rewrite-db = db1name &gt; db2name</span></td> <td><span style="font-size: 12px;">把主控数据库上的db1name数据库镜像处理为从属服务器上的db2name数据库。</span></td> </tr> <tr> <td><span style="font-size: 12px;">report-host = hostname</span></td> <td><span style="font-size: 12px;">从属服务器的主机名; 这项信息只与SHOW SLAVE HOSTS命令有关&#8211;主控服务器可以用这条命令生成一份从属服务器的名单。</span></td> </tr> <tr> <td><span style="font-size: 12px;">slave-compressed-protocol = 1</span></td> <td><span style="font-size: 12px;">主、从服务器使用压缩格式进行通信&#8211;如果它们都支持这么做的话。</span></td> </tr> <tr> <td><span style="font-size: 12px;">slave-skip-errors = n1, n2, &#8230;或all</span></td> <td><span style="font-size: 12px;">即使发生出错代码为n1、n2等的错误，镜像处理工作也继续进行(即不管发生什 么错误，镜像处理工作也继续进行)。如果配置得当，从属服务器不应 该在执行  SQL命令时发生错误(在主控服务器上执行出错的SQL命令不会被发送到从属服务器上做镜像处理);  如果不使用slave-skip-errors选项，从属服务器上的镜像工作就可能因为发生错误而中断，中断后需要有人工参与才能继续进行。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 12px;"><strong>mysqld&#8211;InnoDB：基本设置、表空间文件</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">skip-innodb</span></td> <td><span style="font-size: 12px;">不加载InnoDB数据表驱动程序&#8211;如果用不着InnoDB数据表，可以用这个选项节省一些内存。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb-file-per-table</span></td> <td><span style="font-size: 12px;">为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)。该选项始见于MySQL 4.1。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb-open-file = n</span></td> <td><span style="font-size: 12px;">InnoDB数据表驱动程序最多可以同时打开的文件数(默认设置是300)。如果使用了innodb-file-per-table选项并且需要同时打开很多数据表的话，这个数字很可能需要加大。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_data_home_dir = p</span></td> <td><span style="font-size: 12px;">InnoDB主目录，所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下，这个主目录就是MySQL的数据目录。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_data_file_path = ts</span></td> <td><span style="font-size: 12px;">用来容纳InnoDB为数据表的表空间: 可能涉及一个以上的文件;  每一个表空间文件的最大长度都必须以字节(B)、兆字节(MB)或千兆字节(GB)为单位给出; 表空间文件的名字必须以分号隔开;  最后一个表空间文件还可以带一个autoextend属性和一个最大长度(max:n)。例如，ibdata1:1G;  ibdata2:1G:autoextend:max:2G的意思是:  表空间文件ibdata1的最大长度是1GB，ibdata2的最大长度也是1G，但允许它扩充到2GB。除文件名外，还可以用硬盘分区的设置名来定义表  空间，此时必须给表空间的最大初始长度值加上newraw关键字做后缀，给表空间的最大扩充长度值加上raw关键字做后缀(例如/dev/hdb1:  20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默认设置是ibdata1:10M:autoextend。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_autoextend_increment = n</span></td> <td><span style="font-size: 12px;">带有autoextend属性的表空间文件每次加大多少兆字节(默认设置是8MB)。这个属性不涉及具体的数据表文件，那些文件的增大速度相对是比较小的。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_lock_wait_timeout = n</span></td> <td><span style="font-size: 12px;">如果某个事务在等待n秒(s)后还没有获得所需要的资源，就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被InnoDB数据表驱动 程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_fast_shutdown 0/1</span></td> <td><span style="font-size: 12px;">是否以最快的速度关闭InnoDB，默认设置是1，意思是不把缓存在 INSERT缓存区的数据写入数据表，那些数据将在MySQL服务器下次启动 时再写入  (这么做没有什么风险，因为INSERT缓存区是表空间的一个组成部分，数据不会丢失)。把这个选项设置为0反面危险，因为在计算机关闭时，InnoDB  驱动程序很可能没有足够的时间完成它的数据同步工作，操作系统也许会在它完成数据同步工作之前强行结束InnoDB，而这会导致数据不完整。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 12px;"><strong>mysqld程序：InnoDB&#8211;日志</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">innodb_log_group_home_dir = p</span></td> <td><span style="font-size: 12px;">用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下，InnoDB驱动程序将使用 MySQL数据目录作为自己保存日志文件的位置。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_log_files_in_group = n</span></td> <td><span style="font-size: 12px;">使用多少个日志文件(默认设置是2)。InnoDB数据表驱动程序将以轮转方式依次填写这些文件; 当所有的日志文件都写满以后，之后的日志信息将写入第一个日志文件的最大长度(默认设置是5MB)。这个长度必须以MB(兆字节)或GB(千兆字节)为单 位进行设置。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_flush_log_at_trx_commit = 0/1/2</span></td> <td><span style="font-size: 12px;">这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写 (术语称为&#8221;同步&#8221;)到硬盘上。设置值0的意思是每隔一秒写一次日 志并进行 同步，这可以减少硬盘写操作次数，但可能造成数据丢失;  设置值1(设置设置)的意思是在每执行完一条COMMIT命令就写一次日志并进行同步，这可以防止数据丢失，但硬盘写操作可能会很频繁;  设置值2是一般折衷的办法，即每执行完一条COMMIT命令写一次日志，每隔一秒进行一次同步。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_flush_method = x</span></td> <td><span style="font-size: 12px;">InnoDB日志文件的同步办法(仅适用于UNIX/Linux系统)。这个选项的可取值有两种: fdatasync，用fsync()函数进行同步; O_DSYNC，用O_SYNC()函数进行同步。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_log_archive = 1</span></td> <td><span style="font-size: 12px;">启用InnoDB驱动程序的archive(档案)日志功能，把日志信息写入ib_arch_log_n文件。启用这种日志功能在InnoDB与 MySQL一起使用时没有多大意义(启用MySQL服务器的二进制日志功能就足够用了)。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序&#8211;InnoDB：缓存区的设置和优化</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">innodb_log_buffer_pool_size = n</span></td> <td><span style="font-size: 12px;">为InnoDB数据表及其索引而保留的RAM内存量(默认设置是8MB)。这个参数对速度有着相当大的影响，如果计算机上只运行有 MySQL/InnoDB数据库服务器，就应该把全部内存的80%用于这个用途。</span> <p>&nbsp;</p> </td> </tr> <tr> <td><span style="font-size: 12px;">innodb_log_buffer_size = n</span></td> <td><span style="font-size: 12px;">事务日志文件写操作缓存区的最大长度(默认设置是1MB)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_additional_men_pool_size = n</span></td> <td><span style="font-size: 12px;">为用于内部管理的各种数据结构分配的缓存区最大长度(默认设置是1MB)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_file_io_threads = n</span></td> <td><span style="font-size: 12px;">I/O操作(硬盘写操作)的最大线程个数(默认设置是4)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">innodb_thread_concurrency = n</span></td> <td><span style="font-size: 12px;">InnoDB驱动程序能够同时使用的最大线程个数(默认设置是8)。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size: 14px;"><strong>mysqld程序：其它选项</strong></span></p> <table cellpadding="5" cellspacing="0" border="1"> <tbody> <tr> <td><span style="font-size: 12px;">bind-address = ipaddr</span></td> <td><span style="font-size: 12px;">MySQL服务器的IP地址。如果MySQL服务器所在的计算机有多个IP地址，这个选项将非常重要。</span></td> </tr> <tr> <td><span style="font-size: 12px;">default-storage-engine = type</span></td> <td><span style="font-size: 12px;">新数据表的默认数据表类型(默认设置是MyISAM)。这项设置还可以通过&#8211;default-table-type选项来设置。</span></td> </tr> <tr> <td><span style="font-size: 12px;">default-timezone = name</span></td> <td><span style="font-size: 12px;">为MySQL服务器设置一个地理时区(如果它与本地计算机的地理时区不一样)。</span></td> </tr> <tr> <td><span style="font-size: 12px;">ft_min_word_len = n</span></td> <td><span style="font-size: 12px;">全文索引的最小单词长度工。这个选项的默认设置是4，意思是在创建全文索引时不考虑那些由3个或更少的字符构建单词。</span></td> </tr> <tr> <td><span style="font-size: 12px;">Max-allowed-packet = n</span></td> <td><span style="font-size: 12px;">客户与服务器之间交换的数据包的最大长度，这个数字至少应该大于客户程序将要处理的最大BLOB块的长度。这个选项的默认设置是1MB。</span></td> </tr> <tr> <td><span style="font-size: 12px;">Sql-mode = model1, mode2, &#8230;</span></td> <td><span style="font-size: 12px;">MySQL将运行在哪一种SQL模式下。这个选项的作用是让MySQL与其他的数据库系统保持最大程度的兼容。这个选项的可取值包括ansi、db2、 oracle、no_zero_date、pipes_as_concat。</span></td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="color: red; font-size: 12px;">注意：如果在配置文件里给出的某个选项是mysqld无法识别的，MySQL服务器将不启动。</span></p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/201716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2013-07-12 09:16 <a href="http://www.cppblog.com/guojingjia2006/archive/2013/07/12/201716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> mongdb介绍 (转)</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196573.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 24 Dec 2012 09:19:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196573.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196573.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196573.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196573.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自:http://blog.csdn.net/yczz/article/details/5974235一、NoSQL简述&nbsp; CAP（Consistency，Availabiity，Partition&nbsp;tolerance)理论告诉我们，一个分布式系统不可能满足一致性，可用性和分区容错性这三个需求，最多只能同时满足两个。关系型数据库通过把更新操作写到事务型日志里实现了部分耐用性，...&nbsp;&nbsp;<a href='http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196573.html'>阅读全文</a><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-24 17:19 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mongodb常用命令</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196572.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 24 Dec 2012 09:02:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196572.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196572.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196572.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196572.html</trackback:ping><description><![CDATA[<div><p><strong>shell</strong><strong>操作数据库： </strong></p> <p>&nbsp;</p> <p>&nbsp;&nbsp;1.&nbsp;超级用户相关：</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span></span>&nbsp;1. #进入数据库<span>admin</span></p> <p>use admin</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. #</span>增加或修改用户密码</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db.addUser('name','pwd')</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. #</span>查看用户列表</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.system.users.find()</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. #</span>用户认证</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db.auth('name','pwd')</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. #</span>删除用户</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;db.removeUser('name')</span></p> <p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;6.  #</span>查看所有用户</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;show users</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;7. #</span>查看所有数据库</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;show dbs</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;8. #</span>查看所有的<span>collection</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;show collections</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;9. #</span>查看各<span>collection的状态</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;db.printCollectionStats()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>10. #</span>查看主从复制状态</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;db.printReplicationInfo()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>11. #</span>修复数据库</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.repairDatabase()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>12. #</span>设置记录<span>profiling，0=off 1=slow 2=all</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.setProfilingLevel(1)</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>13. #</span>查看<span>profiling</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;show profile</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;14. #</span>拷贝数据库</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.copyDatabase('mail_addr','mail_addr_tmp')</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;&nbsp;15. #</span>删除<span>collection</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;db.mail_addr.drop()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>16. #</span>删除当前的数据库</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.dropDatabase()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span></span></p> <p><span><span>&nbsp;&nbsp;  </span>2</span>. 增删改</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>1.  #</span>存储嵌套的对象</p> <p>db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]})</p> <p>&nbsp;</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. #</span>存储数组对象</p> <p>db.user_addr.save({'Uid':'yushunzhi@sohu.com','Al':['test-1@sohu.com','test-2@sohu.com']})</p> <p>&nbsp;</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. #</span>根据<span>query条件修改，如果不存在则插入，允许修改多条记录</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.foo.update({'yy':5},{'$set':{'xx':2}},upsert=true,multi=true)</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. #</span>删除<span>yy=5的记录</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;db.foo.remove({'yy':5})</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. #</span>删除所有的记录</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.foo.remove()</span></p> <p>&nbsp;</p> <p><span><span>&nbsp;&nbsp;  </span></span>3. 索引</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span></span>&nbsp;1. #增加索引：<span>1(ascending),-1(descending)</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. db.foo.ensureIndex({firstname: 1, lastname:  1}, {unique: true});</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. #</span>索引子对象</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. db.user_addr.ensureIndex({'Al.Em':  1})</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. #</span>查看索引信息</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6. db.foo.getIndexes()</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7. db.foo.getIndexKeys()</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8. #</span>根据索引名删除索引</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9. db.user_addr.dropIndex('Al.Em_1')</span></p> <p>&nbsp;</p> <p>&nbsp;&nbsp;4. 查询</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span></span><span>&nbsp;&nbsp;1. #</span>查找所有</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;2. db.foo.find()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>3. #</span>查找一条记录</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;4. db.foo.findOne()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;5. #</span>根据条件检索<span>10条记录</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;6. db.foo.find({'msg':'Hello 1'}).limit(10)</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>&nbsp;7. #sort</span>排序</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.  db.deliver_status.find({'From':'ixigua@sina.com'}).sort({'Dt',-1})</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.  db.deliver_status.find().sort({'Ct':-1}).limit(1)</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>10. #count</span>操作</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>11. db.user_addr.count()</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>12. #distinct</span>操作<span>,查询指定列，去重复</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>13. db.foo.distinct('msg')</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>14. #&#8221;&gt;=&#8221;</span>操作</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>15. db.foo.find({"timestamp": {"$gte" : 2}})</span></p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>16. #</span>子对象的查找</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span>17. db.foo.find({'address.city':'beijing'})</span></p> <p><span><span>&nbsp;&nbsp;  </span></span>5. 管理</p> <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </span></span><span>&nbsp;&nbsp;1. #</span>查看<span>collection数据的大小</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. db.deliver_status.dataSize()</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. #</span>查看<span>colleciont状态</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. db.deliver_status.stats()</span></p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5. #</span>查询所有索引的大小</p> <p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.  db.deliver_status.totalIndexSize()</span></p> <p>&nbsp;</p> <p><span>5.&nbsp;</span>advanced queries:高级查询</p> <br />条件操作符<span>&nbsp;<br />$gt  : &gt;&nbsp;<br />$lt : &lt;&nbsp;<br />$gte: &gt;=&nbsp;<br />$lte: &lt;=&nbsp;<br />$ne :  !=</span>、<span>&lt;&gt;&nbsp;<br />$in  : in&nbsp;<br />$nin: not in&nbsp;<br />$all: all&nbsp;<br />$not: </span>反匹配(1.3.3及以上版本)&nbsp;<br /><br />查询<span>  name &lt;&gt; "bruce" and age &gt;= 18 </span>的数据<span>&nbsp;<br />db.users.find({name:  {$ne: "bruce"}, age: {$gte: 18}});&nbsp;<br /><br /></span>查询<span>  creation_date &gt; '2010-01-01' and creation_date &lt;= '2010-12-31'  </span>的数据<span>&nbsp;<br />db.users.find({creation_date:{$gt:new  Date(2010,0,1), $lte:new Date(2010,11,31)});&nbsp;<br /><br /></span>查询<span>  age in (20,22,24,26) </span>的数据<span>&nbsp;<br />db.users.find({age:  {$in: [20,22,24,26]}});&nbsp;<br /><br /></span>查询<span>  age</span>取模10等于<span>0  </span>的数据<span>&nbsp;<br />db.users.find('this.age  % 10 == 0');&nbsp;<br /></span>或者<span>&nbsp;<br />db.users.find({age  : {$mod : [10, 0]}});&nbsp;<br /><br /></span>匹配所有<span>&nbsp;<br />db.users.find({favorite_number  : {$all : [6, 8]}});&nbsp;<br /></span>可以查询出<span>{name:  'David', age: 26, favorite_number: [ 6, 8, 9 ]  }&nbsp;<br /></span>可以不查询出<span>{name:  'David', age: 26, favorite_number: [ 6, 7, 9 ]  }&nbsp;<br /><br /></span>查询不匹配name=B*带头的记录<span>&nbsp;<br />db.users.find({name:  {$not: /^B.*/}});&nbsp;<br /></span>查询<span>  age</span>取模10不等于<span>0  </span>的数据<span>&nbsp;<br />db.users.find({age  : {$not: {$mod : [10, 0]}}});&nbsp;<br /><br />#</span>返回部分字段&nbsp;<br />选择返回age和_id字段(_id字段总是会被返回<span>)&nbsp;<br />db.users.find({},  {age:1});&nbsp;<br />db.users.find({}, {age:3});&nbsp;<br />db.users.find({},  {age:true});&nbsp;<br />db.users.find({ name : "bruce" },  {age:1});&nbsp;<br />0</span>为<span>false,  </span>非0为true&nbsp;<br /><br />选择返回age、address和_id字段<span>&nbsp;<br />db.users.find({  name : "bruce" }, {age:1, address:1});&nbsp;<br /><br /></span>排除返回age、address和_id字段<span>&nbsp;<br />db.users.find({},  {age:0, address:false});&nbsp;<br />db.users.find({ name : "bruce" }, {age:0,  address:false});&nbsp;<br /><br /></span>数组元素个数判断&nbsp;<br />对于<span>{name:  'David', age: 26, favorite_number: [ 6, 7, 9 ] }</span>记录&nbsp;<br />匹配<span>db.users.find({favorite_number:  {$size: 3}});&nbsp;<br /></span>不匹配<span>db.users.find({favorite_number:  {$size: 2}});&nbsp;<br /><br />$exists</span>判断字段是否存在&nbsp;<br />查询所有存在name字段的记录<span>&nbsp;<br />db.users.find({name:  {$exists: true}});&nbsp;<br /></span>查询所有不存在phone字段的记录<span>&nbsp;<br />db.users.find({phone:  {$exists: false}});&nbsp;<br /><br />$type</span>判断字段类型&nbsp;<br />查询所有name字段是字符类型的<span>&nbsp;<br />db.users.find({name:  {$type: 2}});&nbsp;<br /></span>查询所有age字段是整型的<span>&nbsp;<br />db.users.find({age:  {$type: 16}});&nbsp;<br /><br /></span>对于字符字段，可以使用正则表达式&nbsp;<br />查询以字母b或者B带头的所有记录<span>&nbsp;<br />db.users.find({name:  /^b.*/i});&nbsp;<br /><br />$elemMatch(1.3.1</span>及以上版本)&nbsp;<br />为数组的字段中匹配其中某个元素&nbsp;<br /><br />Javascript查询和$where查询&nbsp;<br />查询<span>  age &gt; 18 </span>的记录，以下查询都一样<span>&nbsp;<br />db.users.find({age:  {$gt: 18}});&nbsp;<br />db.users.find({$where: "this.age &gt;  18"});&nbsp;<br />db.users.find("this.age &gt; 18");&nbsp;<br />f = function() {return  this.age &gt; 18} db.users.find(f);&nbsp;<br /><br /></span>排序sort()&nbsp;<br />以年龄升序<span>asc&nbsp;<br />db.users.find().sort({age:  1});&nbsp;<br /></span>以年龄降序<span>desc&nbsp;<br />db.users.find().sort({age:  -1});&nbsp;<br /><br /></span>限制返回记录数量limit()&nbsp;<br />返回5条记录&nbsp;<br />db.users.find().limit(5);&nbsp;<br />返回3条记录并打印信息<span>&nbsp;<br />db.users.find().limit(3).forEach(function(user)  {print('my age is ' + user.age)});&nbsp;<br /></span>结果<span>&nbsp;<br />my  age is 18&nbsp;<br />my age is 19&nbsp;<br />my age is  20&nbsp;<br /><br /></span>限制返回记录的开始点skip()&nbsp;<br />从第3条记录开始，返回5条记录<span>(limit  3,  5)&nbsp;<br />db.users.find().skip(3).limit(5);&nbsp;<br /><br /></span>查询记录条数count()&nbsp;<br />db.users.find().count();&nbsp;<br />db.users.find({age:18}).count();&nbsp;<br />以下返回的不是5，而是user表中所有的记录数量&nbsp;<br />db.users.find().skip(10).limit(5).count();&nbsp;<br />如果要返回限制之后的记录数量，要使用count(true)或者count(非0)&nbsp;<br />db.users.find().skip(10).limit(5).count(true);&nbsp;<br /><br />分组group()&nbsp;<br />假设test表只有以下一条数据<span>&nbsp;<br />{  domain: "www.mongodb.org"&nbsp;<br />, invoked_at: {d:"2009-11-03", t:"17:14:05"}&nbsp;<br />,  response_time: 0.05&nbsp;<br />, http_action: "GET  /display/DOCS/Aggregation"&nbsp;<br />}&nbsp;<br /></span>使用group统计test表11月份的数据count:count(*)、total_time:sum(response_time)、<span>avg_time:total_time/count;&nbsp;<br />db.test.group(&nbsp;<br />{  cond: {"invoked_at.d": {$gt: "2009-11", $lt: "2009-12"}}&nbsp;<br />, key:  {http_action: true}&nbsp;<br />, initial: {count: 0, total_time:0}&nbsp;<br />, reduce:  function(doc, out){ out.count++; out.total_time+=doc.response_time }&nbsp;<br />,  finalize: function(out){ out.avg_time = out.total_time / out.count }&nbsp;<br />}  );&nbsp;<br /><br />[&nbsp;<br />{&nbsp;<br />"http_action" : "GET  /display/DOCS/Aggregation",&nbsp;<br />"count" : 1,&nbsp;<br />"total_time" :  0.05,&nbsp;<br />"avg_time" : 0.05&nbsp;<br />} <br /></span></div>]<br /><br /><br />windows 服务启动:<br /><div><wbr><strong style="background-image: none !important;"><span style="font-family: 'Microsoft YaHei', 'Courier new', Courier, monospace; color: #ffa900; background-image: none !important;">E:\APMServ5.2.6\MongoDb\bin&gt;mongod --logpath E:\APMServ5.2.6\MongoDb\logs\MongoDB.log --logappend --dbpath E:\APMServ5.2.6\MongoDb\data --directoryperdb --serviceName MongoDB --install</span></strong></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-24 17:02 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/24/196572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MongoDb Architecture</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196438.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 19 Dec 2012 03:52:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196438.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196438.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196438.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196438.html</trackback:ping><description><![CDATA[<div>本文图片来自 Ricky Ho 的博文 <a href="http://horicky.blogspot.jp/2012/04/mongodb-architecture.html" target="_blank">MongoDB 构架</a>（<a title="查看 MongoDB 的全部文章" href="http://blog.nosqlfan.com/tags/mongodb" target="_blank">MongoDB</a> Architecture），这是个一听就感觉很宽泛的话题，但是作者在文章中确实对 MongoDB 由内至外的<a title="查看架构的全部文章" href="http://blog.nosqlfan.com/tags/%e6%9e%b6%e6%9e%84" target="_blank">架构</a>进行了剖析。本文截取了其文章中的几张重点架构示意图片进行简单描述。希望对大家有用。</div><div><strong>MongoDB 数据文件内部结构</strong></div><img alt="" src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/p1.png" height="848" width="1222" /><br /><div><ol><li>MongoDB 在数据存储上按命名空间来划分，一个 collection 是一个命名空间，一个索引也是一个命名空间</li><li>同一个命名空间的数据被分成很多个 Extent，Extent 之间使用双向链表连接</li><li>在每一个 Extent 中，保存了具体每一行的数据，这些数据也是通过双向链接连接的</li><li>每一行数据存储空间不仅包括数据占用空间，还可能包含一部分附加空间，这使得在数据 update 变大后可以不移动位置</li><li>索引以 BTree 结构实现</li></ol></div><div>&nbsp; <strong>在 MongoDB 中实现事务</strong></div><img alt="" src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/Picture1.png" height="892" width="1283" /><br /><div>众所周知，MongoDB 只支持对单行记录的原子性修改，并不支持对多行数据的原子操作。但是通过上图中的变态操作，实际你也可以自己实现事务。其步骤如图所未：     <ul><li>第 1 步：先记录一条事务记录，将要修改的多行记录的修改值写到里面，并设置其状态为 init（如果这时候操作中断，那么在重新启动时，会判断到他处于 init 状态，从而将其保存的多行修改操作应用到具体的行上）</li><li>第 2 步：然后更新具体要修改的行，将刚才写的事务记录的标识写到它的 tran 字段中</li><li>第 3 步：将事务记录的状态从 init 变成 pending（如果在这时候操作中断，那么在重新启动时，会判断到它的状态是  pending 的，这时候查看其所有对应的多条要修改的记录，如果其 tran 有值，那么就进行第 4 步，如果没值，说明第 4  步已经执行过了，直接将其状态从 pending 变成 commited 了就行）</li><li>第 4 步：将需要修改的多条记录的相应值修改了，并且 unset 掉之前的 tran 字段</li><li>第 5 步：将事务记录那一条的状态从 pending 变成 commited，事务完成</li></ul>     <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其实上面的步骤并不罕见，在支持事务的 DBMS 中，其事务原子性提交的保证大多都与上面类似。其实事务记录的 tran 那条记录，就类似于这些 DBMS 中的 redolog 一样。</p></div><div>&nbsp; <strong>MongoDB 数据同步</strong></div><img alt="" src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/Picture2.png" height="490" width="945" /><br /><div><div><div>上图是 MongoDB 采用 Replica Sets 模式的同步流程     <ul><li>红色箭头表示写操作写到 Primary 上，然后异步同步到多个 Secondary 上</li><li>蓝色箭头表示读操作可以从 Primary 或 Secondary 任意一个上读</li><li>各个 Primary 与 Secondary 之间一直保持心跳同步检测，用于判断 Replica Sets 的状态</li></ul>     <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>分片机制</strong></p><p><strong><img alt="" src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/Picture3.png" height="825" width="1204" /></strong></p><p><br /><strong></strong></p><div><ul><li><strong>MongoDB 的分片是指定一个分片 key 来进行，数据按范围分成不同的 chunk，每个 chunk 的大小有限制</strong></li><li><strong>有多个分片节点保存这些 chunk，每个节点保存一部分的 chunk</strong></li><li><strong>每一个分片节点都是一个 Replica Sets，这样保证数据的安全性</strong></li><li><strong>当一个 chunk 超过其限制的最大体积时，会分裂成两个小的 chunk</strong></li><li><strong>当 chunk 在分片节点中分布不均衡时，会引发 chunk 迁移操作</strong></li></ul><strong>     <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>服务器角色</strong></p></strong></div><strong><img alt="" src="http://www.cppblog.com/images/cppblog_com/guojingjia2006/Picture4.png" height="761" width="1248" /></strong><p>&nbsp;</p><p><strong></strong></p><div><strong>&nbsp;上面讲了分片的标准，下面是具体在分片时的几种节点角色     <ul><li>客户端访问路由节点 mongos 来进行数据读写</li><li>config 服务器保存了两个映射关系，一个是 key 值的区间对应哪一个 chunk 的映射关系，另一个是 chunk 存在哪一个分片节点的映射关系</li><li>路由节点通过 config 服务器获取数据信息，通过这些信息，找到真正存放数据的分片节点进行对应操作</li><li>路由节点还会在写操作时判断当前 chunk 是否超出限定大小，如果超出，就分列成两个 chunk</li><li>对于按分片 key 进行的查询和 update 操作来说，路由节点会查到具体的 chunk 然后再进行相关的工作</li><li>对于不按分片 key 进行的查询和 update 操作来说，mongos 会对所有下属节点发送请求然后再对返回结果进行合并</li></ul>     <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;更多详细内容请看原文：<a href="http://horicky.blogspot.jp/2012/04/mongodb-architecture.html" target="_blank">MongoDB Architecture</a></p></strong></div><p>&nbsp;</p></div></div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-19 11:52 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MongoDB 学习 (1)</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196437.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 19 Dec 2012 03:34:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196437.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196437.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196437.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196437.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196437.html</trackback:ping><description><![CDATA[<div><p>Mongo是一个高性能，开源，无模式的文档型数据库，它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发，提供了以下功能：</p> <p>&#9670;面向集合的存储：适合存储对象及JSON形式的数据。</p> <p>&#9670;动态查询：Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记，可轻易查询文档中内嵌的对象及数组。</p> <p>&#9670;完整的索引支持：包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式，并生成一个高效的查询计划。</p> <p>&#9670;查询监视：Mongo包含一个监视工具用于分析数据库操作的性能。</p> <p>&#9670;复制及自动故障转移：Mongo数据库支持服务器之间的数据复制，支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。</p> <p>&#9670;高效的传统存储方式：支持二进制数据及大型对象（如照片或图片）。</p> <p>&#9670;自动分片以支持云级别的伸缩性（处于早期alpha阶段）：自动分片功能支持水平的数据库集群，可动态添加额外的机器。</p> <p>MongoDB的主要目标是在键/值存储方式（提供了高性能和高度伸缩性）以及传统的RDBMS系统（丰富的功能）架起一座桥梁，集两者的优势于一身。根据官方网站的描述，Mongo适合用于以下场景：</p> <p>&#9670;网站数据：Mongo非常适合实时的插入，更新与查询，并具备网站实时数据存储所需的复制及高度伸缩性。</p> <p>&#9670;缓存：由于性能很高，Mongo也适合作为信息基础设施的缓存层。在系统重启之后，由Mongo搭建的持久化缓存层可以避免下层的数据源过载。</p> <p>&#9670;大尺寸，低价值的数据：使用传统的关系型数据库存储一些数据时可能会比较昂贵，在此之前，很多时候程序员往往会选择传统的文件进行存储。</p> <p>&#9670;高伸缩性的场景：Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。</p> <p>&#9670;用于对象及JSON数据的存储：Mongo的BSON数据格式非常适合文档化格式的存储及查询。</p> <p>自然，MongoDB的使用也会有一些限制，例如它不适合：</p> <p>&#9670;高度事务性的系统：例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。</p> <p>&#9670;传统的商业智能应用：针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用，数据仓库可能是更合适的选择。</p> <p>&#9670;需要SQL的问题</p> <p>MongoDB支持OS X、Linux及Windows等操作系统，并提供了Python，PHP，Ruby，Java及C++语言的驱动程序，社区中也提供了对Erlang及.NET等平台的驱动程序。</p></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196437.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-19 11:34 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/19/196437.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql 只允许本地登录(tcp/ip or sock)</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/17/196383.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 17 Dec 2012 10:14:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/17/196383.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196383.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/17/196383.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196383.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196383.html</trackback:ping><description><![CDATA[今天弄了下mysql的几个安全设置: 只允许本地登录，允许ssh通过远程登录<br /><br />1.my.cnf<br /><div>#skip-networking<br />bind-address = 127.0.0.1</div><br />此项设置允许 tcp/ip 访问，但是只有127.0.0.1 有可以访问,如果把skip-networking 开启。则只能通过sock连接。<br />顺便提下，<div><p>mysql -h localhost -u eric -p saker</p> <p>mysql -h 127.0.0.1 -u eric -p saker</p> <p>&nbsp;</p><p>这两个命令在skip-networking 开启的时候localhost能正常登录mysql,但是127.0.0.1不能。具体原因如下：</p><p><br /></p> <p>大多数程序将主机名localhost和IP地址127.0.0.1 视作&#8220;本地服务器&#8221;的同义词。</p> <p>&nbsp;</p> <p>但在UNIX系统中，MySQL 有所不同：<br /> 出现localhost时，MySQL会尝试使用一个Unix domain socket 文件来连接本地服务器。</p> <p>要强制使用TCP/IP连接到本地服务器，那就使用IP地址 127.0.0.1 而不是主机名localhost。<br /> 可以通过指定 --protocol=tcp 选项来强制使用TCP/IP进行连接</p> TCP/IP 连接的默认端口号是 3306. </div><br />2.mysql 设置好了，只允许本地登录。但是允许通过ssh远程登录<br />原理：无论是windows还是 linux,第一步就是本地与mysql服务器建立一个ssl tunnel，<br /><div>利用ssh命令在本机开个33xx的端口，这个端口为隧道的入口端口,出口就是数据库的3306（如果默认端口没被修改的话),<br />linux如下： <div><span style="line-height: normal; color: #0000ff;">ssh -NCPf root@localaddress -L 3388:mysqlserver:3306<br /><br /><div><p style="line-height: normal; "><span style="line-height: normal; color: #ff0000; ">参数解释</span></p><p style="line-height: normal;">-C&nbsp;&nbsp;&nbsp; 使用压缩功能，是可选的，加快速度。&nbsp;<br style="line-height: normal; " />-P&nbsp;&nbsp;&nbsp; 用一个非特权端口进行出去的连接。&nbsp;<br style="line-height: normal; " />-f&nbsp;&nbsp;&nbsp; 一旦SSH完成认证并建立port forwarding，则转入后台运行。&nbsp;<br style="line-height: normal; " />-N&nbsp;&nbsp;&nbsp; 不执行远程命令。该参数在只打开转发端口时很有用（V2版本SSH支持）</p></div><br /></span></div></div>1)如果是windows 下用navicat for mysql 之类的数据库管理软件，比较简单，<br />在"常规"选项卡填写主机名为localhost或127.0.0.1,远程数据库的账号和密码<br />"SSH"选项卡填写远程服务器的主机名和ssh端口号，及登录的用户和密码,测试连接是否成功<br />2)windows 暂时没找出类似<div><span style="line-height: normal; color: #0000ff; ">ssh -NCPf root@localaddress -L 3388:mysqlserver:3306</span></div>命令安静模式下建立ssh tunnel。 我用了putty试了下。连接可以成功。呆后续研究<br /><br />3.mysql 主从备份使用ssh tunnel,下面摘自别人文章，待验证<br /><div><dl><dt>1). 备份初始数据。 </dt><dd> 关闭所有相关的数据更新操作程序，或者对要备份的数据库加锁，避免更新，然后用 tar 备份到从服务器上。或者可以用mysqlhotcopy。 </dd><dt> 2). 需要在主服务器上，配置日志功能</dt><dd> 这需要重启服务，使其启用日志功能。配置文件 my.cnf 可以放在 mysql 的安装目录中。<br /> <pre>[mysqld] <br />server-id=1<br /> log-bin=mydb-bin<br /> binlog-do-db=mydb  </pre>重启服务后，可以在数据目录下，看见该数据库的日志文件，并且可以通过 "show master status"，查看到主服务器的状态。 </dd><dt> 3). 设置备用用户 </dt><dd> <pre>mysql&gt;GRANT REPLICATION SLAVE ON *.* TO backup@'localhost' IDENTIFIED BY 'backup';</pre>这里之所以用本地连接，是因为后面采用 ssh 隧道连接 mysql </dd><dt> 4). 设置从服务器</dt><dd> <pre>[mysqld]<br /> server-id=2<br /> master-host=127.0.0.1<br /> master-port=3307<br /> master-user=backup<br /> master-password=backup<br /> master-connect-retry=10<br /> report-host=127.0.0.1 </pre> </dd><dt> 5). 远程连接隧道</dt><dd> <pre>ssh -f -N -4 -L 3307:127.0.0.1:3306 mysqlm@remotemysql  </pre></dd><dt> 6). 启动从服务器</dt><dd>可以通过 "show processlist"，查看备份情况。并且可以查看mysql的错误日志，了解是否连接正常，同步备份功能是否工作正常。  </dd></dl></div>4.因为使用yii框架在写一个项目，所以远程mysql禁止直接登录后，yii的配置文件也要相应修改，linux下比较简单，可参看以下<br /><div>http://www.yiiframework.com/forum/index.php/topic/30678-mysql-through-ssh-tunnel/<br /><div>windows待续......</div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-17 18:14 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/17/196383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Amoeba for MySQL---分布式数据库Proxy解决方案</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196220.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Thu, 13 Dec 2012 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196220.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/196220.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/196220.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/196220.html</trackback:ping><description><![CDATA[<div><div id="sina_keyword_ad_area2"  "=""> 			<p>Amoeba for MySQL 位于Client、Database Server(s)之间，具有负载均衡、高可用性、sql过滤、可承受高并发、读写分离、Query Route（解析sql query语句，并且根据条件与预先设定的规则，请求到指定的目标数据库。可并发请求多台数据库合并结果）、对客户端透明，能降低数据切分带来的复杂多数据库结构、数据切分规则给应用带来的影响。适用mysql 4.1或者以上版本（mysql 协议版本：10）暂时不支持事务、DDL语句目前只会分配给默认的数据库执行，运行环境至少需要运行 mysql 4.1以上服务, Java 1.5或以上版本。<br /> Amoeba与mysql proxy存在一些区别。在mysql proxy上面如果想要读写分离并且读集群、写集群机器比较多情况下，用mysql proxy 需要自己写一个LUA脚本，目前mysql proxy没有现成的比较好的lua脚本。amoeba只需要进行相关的配置就可以满足需求。</p> <p><br /> 一、Mysql Master/Slave 结构之下的读写分离：<br /> Master： serverM （主库，接收写操作）<br /> slaves：serverA、serverB、serverC（3个辅库，只读操作）</p> <p> amoeba提供读写分离pool相关配置，可配置serverA、serverB、serverC形成一个虚拟的virtualSlave,该配置提供LB,failover/failbackup功能.<br />  &nbsp;<wbr><br /> &lt;dbServer name="virtualSlave" virtual="true"&gt;&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;poolConfig&gt;&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;className&gt;com.meidusa.amoeba.server.MultipleServerPool&lt;/className&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;!-- 负载均衡参数 1=ROUNDROBIN , 2=WEIGHTBASED --&gt;&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="loadbalance"&gt;1&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;!-- 参与该pool负载均衡的poolName列表以逗号分割 --&gt;&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="poolNames"&gt;serverA,serverB,serverC&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;/poolConfig&gt;&nbsp;<wbr><br /> &lt;/dbServer&gt;&nbsp;<wbr></p> <p><br /> &lt;dbServer name="virtualSlave" virtual="true"&gt;<br /> &nbsp;<wbr>&lt;poolConfig&gt;<br /> &nbsp;<wbr>&nbsp;<wbr>&lt;className&gt;com.meidusa.amoeba.server.MultipleServerPool&lt;/className&gt;<br />  &nbsp;<wbr>&nbsp;<wbr>&lt;!-- 负载均衡参数 1=ROUNDROBIN , 2=WEIGHTBASED --&gt;<br /> &nbsp;<wbr>&nbsp;<wbr>&lt;property name="loadbalance"&gt;1&lt;/property&gt;<br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&lt;!-- 参与该pool负载均衡的poolName列表以逗号分割 --&gt;<br /> &nbsp;<wbr>&nbsp;<wbr>&lt;property name="poolNames"&gt;serverA,serverB,serverC&lt;/property&gt;<br />  &nbsp;<wbr>&lt;/poolConfig&gt;<br /> &lt;/dbServer&gt;</p> <p>&nbsp;<wbr></p> <p>如果不启用数据切分功能，那么只需要配置QueryRouter属性<br /> wirtePool=serverM<br /> readPool=virtualSlave</p> <p> &lt;queryRouter&gt;&nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;className&gt;com.meidusa.amoeba.mysql.parser.MysqlQueryRouter&lt;/className&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="LRUMapSize"&gt;1500&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="defaultPool"&gt;serverM&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="writePool"&gt;serverM&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="readPool"&gt;virtualSlave&lt;/property&gt;&nbsp;<wbr><br />  &nbsp;<wbr><br /> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &lt;property name="needParse"&gt;true&lt;/property&gt;&nbsp;<wbr><br />  &lt;/queryRouter&gt;&nbsp;<wbr></p> <p> &nbsp;<wbr>&lt;queryRouter&gt;<br /> &nbsp;<wbr>&nbsp;<wbr>&lt;className&gt;com.meidusa.amoeba.mysql.parser.MysqlQueryRouter&lt;/className&gt;<br />  &nbsp;<wbr>&nbsp;<wbr>&lt;property name="LRUMapSize"&gt;1500&lt;/property&gt;<br />  &nbsp;<wbr>&nbsp;<wbr>&lt;property name="defaultPool"&gt;serverM&lt;/property&gt;</p> <p>&nbsp;<wbr>&nbsp;<wbr>&lt;property name="writePool"&gt;serverM&lt;/property&gt;<br />  &nbsp;<wbr>&nbsp;<wbr>&lt;property name="readPool"&gt;virtualSlave&lt;/property&gt;</p> <p>&nbsp;<wbr>&nbsp;<wbr>&lt;property name="needParse"&gt;true&lt;/property&gt;<br />  &nbsp;<wbr>&lt;/queryRouter&gt;</p> <p><br /> client发送过来的update/insert/delete语句被发送到wirtePool，将select语句发送到readPool机器执行。</p> <p>&nbsp;<wbr></p> <p>二、数据切分方面：<br /> 这方面amoeba显然也很容易，举个数据切分例子：</p> <p>select * from user_event where user_id='test' and&nbsp;<wbr> gmt_create between Sysdate() -1 and Sysdate()</p> <p>如果根据gmt_create 时间进行数据切分，比如6个月进行切分一次，amoeba提供利用类似sql表达式进行数据切分：</p> <p>规则1：GMT_CREATE &gt; to_date('2008-01-01','yyyy-mm-dd') and GMT_CREATE &lt; to_date('2008-05-31','yyyy-mm-dd')</p> <p>规则1对应服务器1</p> <p>规则2：GMT_CREATE &gt; to_date('2008-06-01','yyyy-mm-dd') and GMT_CREATE &lt; to_date('2008-12-31','yyyy-mm-dd')</p> <p>规则2对应服务器2<br /> 上面的sql的条件 gmt_create 与规则里面的的gmt_create 进行交集判断，如果存在交集则表示符合规则，则会将sql转移到 规则1 的相应的服务器上面执行。</p> <p> 利用amoeba写出这种类似规则很容易，但是要想做到数据切分以后可线性扩容，那么这样的规则需要自己根据业务实际情况进行设置。amoeba可同时将 sql并发分发到多台服务器、然后将结果合并再反馈给客户端，而且amoeba内部采用无阻塞模式，工作线程是不会等待的,并发请求多台 database server情况下，客户端等待的时间基本上面是性能最差的那台database server＋amoeba内部解析协议时间。</p> <p><br /> 中文文档地址： <a href="http://amoeba.sourceforge.net/amoeba.pdf">http://amoeba.sourceforge.net/amoeba.pdf</a><br />  amoeba 未来发展方向： <a href="http://amoeba.sourceforge.net/amoeba-big-picture.pdf">http://amoeba.sourceforge.net/amoeba-big-picture.pdf</a></p> <p>文件下载： <a href="http://www.sourceforge.net/projects/amoeba">http://www.sourceforge.net/projects/amoeba</a><br />  amoeba 开发者博客: <a href="http://amoeba.meidusa.com/">http://amoeba.meidusa.com</a></p>							 		</div></div>转自:<div>http://blog.sina.com.cn/s/blog_499740cb0100g45w.html</div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/196220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-12-13 17:14 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/12/13/196220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysqldump备份数据库 MySQL</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/08/10/186826.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Fri, 10 Aug 2012 06:35:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/08/10/186826.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/186826.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/08/10/186826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/186826.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/186826.html</trackback:ping><description><![CDATA[<div><div id="sina_keyword_ad_area2"  "=""> 			<p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">mysql</span><span style="font-family: simsun;">数据库备份一般使用命令</span><span style="font-family: 'Courier new';">mysqldump</span><span style="font-family: simsun;">，这个命令会在屏幕打印指定数据库、数据表的创建的</span><span style="font-family: 'Courier new';">SQL</span><span style="font-family: simsun;">语句和数据表中数据的插入</span><span style="font-family: 'Courier new';">SQL</span><span style="font-family: simsun;">语句。该命令导出的</span><span style="font-family: 'Courier new';">SQL</span><span style="font-family: simsun;">语句在不同数据库之间是可移植的。</span></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">mysqldump</span><span style="font-family: simsun;">还可以同时导出包含</span><span style="font-family: 'Courier new';">sql</span><span style="font-family: simsun;">语句的文件和以特定符号分割的数据文件</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">&nbsp;<wbr></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: simsun;">下面介绍</span><span style="font-family: 'Courier new';">mysqldump</span><span style="font-family: simsun;">的用法：</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> &nbsp;<wbr></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">mysqldump</span><span style="font-family: simsun;">的用法有三种：</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">mysqldump [options] database_name [table1 table2 ...]</p> <p style="margin: 0in 0in 0in 0.375in; font-family: simsun; font-size: 10.5pt;"> 备份特定数据库，可以指定特定表，以空格分隔</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">mysqldump [options] --database database1 database2</p> <p style="margin: 0in 0in 0in 0.375in; font-family: simsun; font-size: 10.5pt;"> 备份特定数据库</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">mysqldump [options] --all-database / mysqldump [options] -A</p> <p style="margin: 0in 0in 0in 0.375in; font-family: simsun; font-size: 10.5pt;"> 备份所有数据库</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">&nbsp;<wbr></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">mysqldump</span><span style="font-family: simsun;">还有很多选项，下面根据选项的使用频率依次介绍</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--user=user_name / -u user_name</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">连接数据库的用户，</span><span style="font-family: 'Courier new';">-u</span><span style="font-family: 宋体;">后面的空格可有可无</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--password[=password] / -p[password]</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">注意</span><span style="font-family: 'Courier new';">-p</span><span style="font-family: 宋体;">后面跟密码时，中间不能间隔空格号，表示连接数据库用户对应的密码</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--host=host_name / -h host_name</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">注意</span><span style="font-family: 'Courier new';">-h</span><span style="font-family: 宋体;">后面一定要有空格，数据库所在服务器的</span><span style="font-family: 'Courier new';">ip</span><span style="font-family: 宋体;">地址或者域名</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--port=port_num / -P port_num</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">服务器上数据库通讯使用的端口号，</span><span style="font-family: 'Courier new';">-P</span><span style="font-family: 宋体;">后的空格可有可无</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--result-file=file / -r file</p> <p style="margin: 0in 0in 0in 0.375in; font-family: 宋体; font-size: 10.5pt;"> 指定输出的信息到文件，而终端不输出文字</p> <p style="margin: 0in 0in 0in 0.375in; font-family: 宋体; font-size: 10.5pt;"> 使用该选项要好于终端的输出重定向，因为重定向可能会发生字符编码的问题</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> =====================================================================================</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--tab=path / -T path</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">产生</span><span style="font-family: 'Courier new';">tab</span><span style="font-family: 宋体;">分割的数据文件。对于每个转储的表，</span><span style="font-family: 'Courier new'; font-weight: bold;">mysqldump</span><span style="font-family: 宋体;">创建一个包含创建表的</span><span style="font-family: 'Courier new';">CREATE TABLE</span><span style="font-family: 宋体;">语句的</span><span style="font-style: italic; font-family: 'Courier new';">tbl_name</span><span style="font-family: 'Courier new';">.sql</span><span style="font-family: 宋体;">文件，和一个包含其数据的</span><span style="font-style: italic; font-family: 'Courier new';">tbl_name</span><span style="font-family: 'Courier new';">.txt</span><span style="font-family: 宋体;">文件。选项值定义写入文件的目录。</span><span style="font-family: Calibri;">默认情况，</span><span style="font-family: 'Courier new';">.txt</span><span style="font-family: 宋体;">数据文件的格式是在列值和每行后面的新行之间使用</span><span style="font-family: 'Courier new';">tab</span><span style="font-family: 宋体;">字符。可以使用</span><span style="font-family: 'Courier new';">--fields-</span><span style="font-style: italic; font-family: 'Courier new';">xxx</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier new';">--</span><span style="font-family: 宋体;">行</span><span style="font-family: 'Courier new';">--</span><span style="font-style: italic; font-family: 'Courier new';">xxx</span><span style="font-family: 宋体;">选项明显指定格式。</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">需要注意的是：该选项其实是间接调用了两个命令，第一个命令类似</span><span style="font-family: 'Courier new';">SHOW CREATE TABLE</span><span style="font-family: 宋体;">，第二个产生数据文件的命令等同于</span><span style="font-family: 'Courier new';">SELECT &#8230; INTO OUTFILE '</span><span style="font-family: 宋体;">文件路径</span><span style="font-family: 'Courier new';">'</span><span style="font-family: 宋体;">，所以和</span><span style="font-family: 'Courier new';">SELECT &#8230; INTO OUTFILE</span><span style="font-family: 宋体;">的特点相同，产生的数据文件只能存到服务器中，而不能存到客户机，所以对指定的目录路径</span><span style="font-family: 'Courier new';">path</span><span style="font-family: 宋体;">是针对服务器操作系统的，并且对目录路径</span><span style="font-family: 'Courier new';">path</span><span style="font-family: 宋体;">要有读写的用户权限。如果想把类似的数据格式化导出文件存到客户机，可以参考</span><span style="font-family: 'Courier new';">$ &gt;mysql -e "SELECT &#8230;&nbsp;<wbr> FROM &#8230; WHERE &#8230; " &gt; file_path</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --fields-terminated-by=</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">该选项连同</span><span style="font-family: 'Courier new';">-T</span><span style="font-family: 宋体;">选项一起使用，规定了数据域以什么结束，参数为字符串，默认为</span><span style="font-family: 'Courier new';">\t</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --fields-enclosed-by=</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">该选项连同</span><span style="font-family: 'Courier new';">-T</span><span style="font-family: 宋体;">选项一起使用，规定了数据域用什么符号扩起来，默认为空，一般可以是双引号、括号等</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --fields-optionally-enclosed-by=</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">该选项连同</span><span style="font-family: 'Courier new';">-T</span><span style="font-family: 宋体;">选项一起使用，规定了数据域可以用什么符号括起来，因为为只有部分数据用这些符号括起来</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --fields-escaped-by=</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">该选项连同</span><span style="font-family: 'Courier new';">-T</span><span style="font-family: 宋体;">选项一起使用，规定了转义字符，参数为字符，默认为</span><span style="font-family: 'Courier new';">\</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --lines-terminated-by=</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">该选项连同</span><span style="font-family: 'Courier new';">-T</span><span style="font-family: 宋体;">选项一起使用，规定了数据行以什么结束，参数为字符串，</span><span style="font-family: 'Courier new';">windows</span><span style="font-family: 宋体;">默认为</span><span style="font-family: 'Courier new';">\r\n</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> =====================================================================================</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--add-drop-database</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">在每个</span><span style="font-family: 'Courier new';">CREATE DATABASE</span><span style="font-family: simsun;">语句前添加</span><span style="font-family: 'Courier new';">DROP DATABASE</span><span style="font-family: simsun;">语句</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--compatible=name</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">产生与其它数据库系统或旧的</span><span style="font-family: 'Courier new';">MySQL</span><span style="font-family: 宋体;">服务器更兼容的输出。值可以为</span><span style="font-family: 'Courier new';">ansi</span><span style="font-family: 宋体;">（标准</span><span style="font-family: 'Courier new';">SQL</span><span style="font-family: 宋体;">）、</span><span style="font-family: 'Courier new';">mysql323</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">mysql40</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">postgresql</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">oracle</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">mssql</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">db2</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">maxdb</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">no_key_options</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">no_table_options</span><span style="font-family: 宋体;">或者</span><span style="font-family: 'Courier new';">no_field_options</span><span style="font-family: 宋体;">。同时使用几个选项，要用逗号将它们隔开</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 'Courier new';">No_key_options</span><span style="font-family: 宋体;">不输出</span><span style="font-family: 'Courier new';">mysql</span><span style="font-family: 宋体;">专用索引选项</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 'Courier new';">No_table_options</span><span style="font-family: 宋体;">不输出</span><span style="font-family: 'Courier new';">mysql</span><span style="font-family: 宋体;">专用表选项，如</span><span style="font-family: 'Courier new';">ENGINE=MyISAM</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 'Courier new';">No_field_options</span><span style="font-family: 宋体;">不输出</span><span style="font-family: 'Courier new';">mysql</span><span style="font-family: 宋体;">专用列选项</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --compact</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">产生少量输出</span><span style="font-family: simsun;">，</span><span style="font-family: Calibri;">该选项</span><span style="font-family: simsun;">相当于</span><span style="font-family: 'Courier new';">--comments=0</span><span style="font-family: simsun;">、</span><span style="font-family: 'Courier new';">--skip-add-drop-table</span><span style="font-family: simsun;">、</span><span style="font-family: 'Courier new';">--no-set-name</span><span style="font-family: simsun;">、</span><span style="font-family: 'Courier new';">--skip-disable-key</span><span style="font-family: simsun;">和</span><span style="font-family: 'Courier new';">--skip-add-locking</span><span style="font-family: simsun;">一起使用</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --comments[={0|1}]</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">如果设置为</span> <span style="font-family: 'Courier new';">0</span><span style="font-family: simsun;">，禁止转储文件中的其它信息，例如程序版本、服务器版本和主机。</span><span style="font-family: 'Courier new';">--skip</span><span style="font-family: 'Courier new';">-</span><span style="font-family: 'Courier new';">comments</span><span style="font-family: simsun;">与</span><span style="font-family: 'Courier new';">--comments=0</span><span style="font-family: simsun;">的结果相同，</span> <span style="font-family: simsun;">默认值为</span><span style="font-family: 'Courier new';">1</span><span style="font-family: simsun;">，即包括额外信息</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--compress / -C</p> <p style="margin: 0in 0in 0in 0.375in; font-family: 宋体; font-size: 10.5pt;"> 如果客户端和服务器都支持压缩，则压缩双方传送的所有信息</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --default-character-set=<span style="font-style: italic;">charset</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">使用</span><span style="font-style: italic; font-family: 'Courier new';">charset</span><span style="font-family: 'Courier new';">as</span><span style="font-family: 宋体;">默认字符集，</span><span style="font-family: Calibri;">如果没有指定，</span><span style="font-family: 'Courier new'; font-weight: bold;">mysqldump</span><span style="font-family: 宋体;">使用</span><span style="font-family: 'Courier new';">utf8</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --delayed-insert</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">使用</span><span style="font-family: 'Courier new';">INSERT DELAYED</span><span style="font-family: 宋体;">语句插入行</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --default-character-set=<span style="font-style: italic;">charset</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">使用</span><span style="font-style: italic; font-family: 'Courier new';">charset</span><span style="font-family: 宋体;">作为默认字符集</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --allow-keywords</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">允许创建关键字列名</span><span style="font-family: simsun;">，</span><span style="font-family: Calibri;">应在每个列名前面加上表名前缀</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> ====================================================================================</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --opt</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">该选项</span><span style="font-family: 宋体;">应该同时代表优化</span><span style="font-family: 'Courier new';">(optimize)</span><span style="font-family: 宋体;">和选项</span><span style="font-family: 'Courier new';">(option)</span><span style="font-family: 宋体;">意思，</span><span style="font-family: 宋体; font-weight: bold;">默认开启</span><span style="font-family: 宋体;">，相当于同时开启以下多个选项，省得用户每次都键入选项：</span><span style="font-family: 'Courier new';">--add-drop-table</span> <span style="font-family: 'Courier new';">--add-locking --create-option --disable-keys</span> <span style="font-family: 'Courier new';">--extended-insert --lock-tables --quick --set-charset</span><span style="font-family: 宋体;">。它可以给出很快的转储操作并产生一个可以很快装入</span><span style="font-family: 'Courier new';">MySQL</span><span style="font-family: 宋体;">服务器的转储文件。</span><span style="font-family: 宋体; font-weight: bold;">可以用</span><span style="font-family: 'Courier new'; font-weight: bold;">--skip-opt</span><span style="font-family: 宋体; font-weight: bold;">禁用</span><span style="font-family: 宋体;">。要想只禁用确信用</span><span style="font-family: 'Courier new';">-opt</span><span style="font-family: 宋体;">启用的选项，使用</span><span style="font-family: 'Courier new';">--skip</span><span style="font-family: 宋体;">形式；例如，</span><span style="font-family: 'Courier new';">--skip-add-drop-tables</span><span style="font-family: 宋体;">或</span><span style="font-family: 'Courier new';">--skip-quick</span></p> <p style="margin: 0in 0in 0in 0.375in; font-family: 宋体; font-size: 10.5pt;"> <span style="font-weight: bold;">该选项比较重要，但是由于默认开启，所以不常用</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--add-drop-table</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">在每个</span><span style="font-family: 'Courier new';">CREATE TABLE</span><span style="font-family: simsun;">语句前添加</span><span style="font-family: 'Courier new';">DROP TABLE</span><span style="font-family: simsun;">语句</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--add-locking</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">用</span><span style="font-family: 'Courier new';">LOCK TABLES</span><span style="font-family: simsun;">和</span><span style="font-family: 'Courier new';">UNLOCK TABLES</span><span style="font-family: simsun;">语句引用每个表转储，重载转储文件时插入得更快</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --create-option</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">在</span><span style="font-family: 'Courier new';">CREATE TABLE</span><span style="font-family: 宋体;">语句中包括所有</span><span style="font-family: 'Courier new';">MySQL</span><span style="font-family: 宋体;">表选项</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --disable-keys / -K</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">对于每个表，用</span><span style="font-family: 'Courier new';">ALTER TABLE</span> <span style="font-style: italic; font-family: 'Courier new';">tbl_name</span> <span style="font-family: 'Courier new';">DISABLE KEYS;</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier new';">ALTER TABLE</span> <span style="font-style: italic; font-family: 'Courier new';">tbl_name</span> <span style="font-family: 'Courier new';">ENABLE KEYS;</span><span style="font-family: 宋体;">语句引用</span><span style="font-family: 'Courier new';">INSERT</span><span style="font-family: 宋体;">语句。因为在插入所有行后创建索引，所以这样可以更快地装载转储文件，该选项只适合</span><span style="font-family: 'Courier new';">MyISAM</span><span style="font-family: 宋体;">表。</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --extended-insert / -e</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">默认开启，</span><span style="font-family: Calibri;">使用包括几个</span><span style="font-family: 'Courier new';">VALUES</span><span style="font-family: 宋体;">的多行</span><span style="font-family: 'Courier new';">INSERT</span><span style="font-family: 宋体;">语法。这样使转储文件更小，重载文件时可以加速插入</span></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">--lock-tables</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Courier new';">-l</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 宋体;">开始转储前锁定所有表。用</span><span style="font-family: 'Courier new';">READ LOCAL</span><span style="font-family: 宋体;">锁定表以允许并行插入</span><span style="font-family: 'Courier new';">MyISAM</span><span style="font-family: 宋体;">表。对于事务表例如</span><span style="font-family: 'Courier new';">InnoDB</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier new';">BDB</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Courier new';">--single-transaction</span><span style="font-family: 宋体;">是一个更好的选项，因为它不根本需要锁定表。</span></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">--quick</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Courier new';">-q</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">该选项用于转储大的表。它强制</span><span style="font-family: 'Courier new'; font-weight: bold;">mysqldump</span><span style="font-family: 宋体;">从服务器一次一行地检索表中的行而不是检索所有行并在输出前将它缓存到内存中</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --set-charset</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">将</span><span style="font-family: 'Courier new';">SET NAMES</span> <span style="font-style: italic; font-family: 'Courier new';">default_character_set</span><span style="font-family: 宋体;">加到输出中。该选项默认启用。要想禁用</span><span style="font-family: 'Courier new';">SET NAMES</span><span style="font-family: 宋体;">语句，使用</span><span style="font-family: 'Courier new';">--skip-set-charset</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> =====================================================================================</p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;">--complete-insert / -c</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">使用包括列名的完整的</span><span style="font-family: 'Courier new';">INSERT</span><span style="font-family: 宋体;">语句</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --single-transaction</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">该选项从服务器转储数据之前发出一个</span><span style="font-family: 'Courier new';">BEGIN SQL</span><span style="font-family: 宋体;">语句。它只适用于事务表，例如</span><span style="font-family: 'Courier new';">InnoDB</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier new';">BDB</span><span style="font-family: 宋体;">，因为然后它将在发出</span><span style="font-family: 'Courier new';">BEGIN</span><span style="font-family: 宋体;">而没有阻塞任何应用程序时转储一致的数据库状态。</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">当使用该选项时，应记住只有</span><span style="font-family: 'Courier new';">InnoDB</span><span style="font-family: 宋体;">表能以一致的状态被转储。例如，使用该选项时任何转储的</span><span style="font-family: 'Courier new';">MyISAM</span><span style="font-family: 宋体;">或</span><span style="font-family: 'Courier new';">HEAP</span><span style="font-family: 宋体;">表仍然可以更改状态。</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: 'Courier new';">--single-transaction</span><span style="font-family: 宋体;">选项和</span><span style="font-family: 'Courier new';">--lock-tables</span><span style="font-family: 宋体;">选项是互斥的，因为</span><span style="font-family: 'Courier new';">LOCK TABLES</span><span style="font-family: 宋体;">会使任何挂起的事务隐含提交。</span><span style="font-family: Calibri;">要想转储大的表，应结合</span><span style="font-family: 'Courier new';">--quick</span><span style="font-family: 宋体;">使用该选项</span></p> <p style="margin: 0in; font-size: 10.5pt;"><span style="font-family: 'Courier new';">--lock-all-tables</span><span style="font-family: 宋体;">，</span><span style="font-family: 'Courier new';">-x</span></p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">所有数据库中的所有表加锁。在整体转储过程中通过全局读锁定来实现。该选项自动关闭</span><span style="font-family: 'Courier new';">--single-transaction</span><span style="font-family: 宋体;">和</span><span style="font-family: 'Courier new';">--lock-tables</span></p> <p style="margin: 0in; font-family: 'Courier new'; font-size: 10.5pt;"> --hex-blob</p> <p style="margin: 0in 0in 0in 0.375in; font-size: 10.5pt;"> <span style="font-family: Calibri;">使用十六进制符号转储二进制字符串列</span><span style="font-family: 'Courier new';">(</span><span style="font-family: 宋体;">例如，</span><span style="font-family: 'Courier new';">'abc'</span> <span style="font-family: 宋体;">变为</span><span style="font-family: 'Courier new';">0x616263)</span><span style="font-family: 宋体;">。影响到的列有</span><span style="font-family: 'Courier new';">BINARY</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">VARBINARY</span><span style="font-family: 宋体;">、</span><span style="font-family: 'Courier new';">BLOB</span></p>							 		</div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/186826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-08-10 14:35 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/08/10/186826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库添加字段</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185870.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 01 Aug 2012 04:27:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185870.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/185870.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185870.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/185870.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/185870.html</trackback:ping><description><![CDATA[<div>通用式： alter table [表名] add [字段名] 字段属性 default 缺省值 default 是可选参数<br />增加字段： alter table [表名] add 字段名 smallint default 0 增加数字字段，整型，缺省值为0 <br />alter table [表名] add 字段名 int default 0 增加数字字段，长整型，缺省值为0<br />alter table [表名] add 字段名 single default 0 增加数字字段，单精度型，缺省值为0 <br />alter table [表名] add 字段名 double default 0 增加数字字段，双精度型，缺省值为0<br />alter table [表名] add 字段名 Tinyint default 0 增加数字字段，字节型，缺省值为0<br /><br />alter table [表名] add 字段名 text [null] 增加备注型字段,[null]可选参数<br />alter table [表名] add 字段名 memo [null] 增加备注型字段,[null]可选参数<br /><br />alter table [表名] add 字段名 varchar(N) [null] 增加变长文本型字段 大小 为N(1～255)<br />alter table [表名] add 字段名 char [null] 增加定长文本型字段 大小固定为255<br /><br />alter table [表名] add 字段名 Datetime default 函数 增加日期型字段，其中 函数 可以是 now(),date()等，表示缺省值<br />(上面都是最常用的，还有其他的属性，可以参考下面的数据类型描述)<br /><br />删除字段： alter table [表名] drop 字段名<br /><br />修改变长文本型字段的大小：alter table [表名] alter 字段名 varchar(N) <br /><br />删除表： drop table [表名]<br /><br />创建表：<br />sql="CREATE TABLE [表名] ([字段1,并设置为主键] int IDENTITY (1, 1) NOT NULL CONSTRAINT PrimaryKey PRIMARY KEY,"&amp;_<br />"[字段2] varchar(50),"&amp;_<br />"[字段3] single default 0,"&amp;_<br />"[字段4] varchar(100) null,"&amp;_<br />"[字段5] smallint default 0,"&amp;_<br />"[字段6] int default 0,"&amp;_<br />"[字段7] date default date(),"&amp;_<br />"[字段8] int default 1)"<br />conn.execute sql<br /><br />有null 的表示字段允许零长</div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/185870.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-08-01 12:27 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysqldump</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Wed, 01 Aug 2012 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/185869.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/185869.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/185869.html</trackback:ping><description><![CDATA[<div><div> <p><span style="font-size: medium;"><strong>命令行下具体用法如下：&nbsp; </strong></span></p> <p><span style="font-size: medium;"><strong>mysqldump -u用戶名 -p密码 <span style="color: #ff0000;">-d</span> 数据库名&nbsp;表名 &gt; 脚本名;</strong></span></p> <p>&nbsp;</p> <p>&nbsp;</p> <p><span style="font-size: medium;">导出整个数据库结构和数据<br />mysqldump -h localhost -uroot -p123456&nbsp;database &gt; dump.sql</span></p> <p>&nbsp;</p> <p><span style="font-size: medium;">导出单个数据表结构和数据<br />mysqldump -h localhost -uroot -p123456&nbsp; database table &gt; dump.sql</span></p> <p>&nbsp;</p> <p>&nbsp;</p> <div> <p><span style="color: #000000; font-size: medium;">导出整个数据库结构（不包含数据）<br />mysqldump -h localhost -uroot -p123456&nbsp;<span> -d&nbsp;database &gt; dump.sql</span></span></p> <p>&nbsp;</p> <p><span style="color: #000000; font-size: medium;">导出单个数据表结构（不包含数据）<br />mysqldump -h localhost -uroot -p123456&nbsp; <span>-d&nbsp;database table &gt; dump.sql</span></span></p> </div> </div></div><img src ="http://www.cppblog.com/guojingjia2006/aggbug/185869.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-08-01 12:23 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/08/01/185869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql 触发器</title><link>http://www.cppblog.com/guojingjia2006/archive/2012/01/16/164247.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Mon, 16 Jan 2012 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2012/01/16/164247.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/164247.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2012/01/16/164247.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/164247.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/164247.html</trackback:ping><description><![CDATA[<div id="blog_text" class="cnt"><font size="5">1&nbsp;&nbsp; 引言<br /><br /></font>Mysql的触发器和存储过程一样，都是嵌入到mysql的一段程序。触发器是mysql5新增的功能，目前线上凤巢系统、北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本，很多程序比如fc-star管理端，sfrd(das)，dorado都会用到触发器程序，实现对于数据库增、删、改引起事件的关联操作。本文介绍了触发器的类型和基本使用方法，讲述了触发器使用中容易产生的误区，从mysql源码中得到触发器执行顺序的结论，本文最后是实战遭遇的触发器经典案例。没有特殊说明时，本文的实验均基于mysql5.0.45版本。<br /><br /><font size="5">2&nbsp;&nbsp; Mysql触发器的类型</font><br /><br /><font size="4">2.1&nbsp;&nbsp; Mysql触发器的基本使用</font><br /><br />创建触发器。创建触发器语法如下：<br /><br />CREATE TRIGGER trigger_name trigger_time trigger_event<br />ON tbl_name FOR EACH ROW trigger_stmt<br /><br />其中trigger_name标识触发器名称，用户自行指定；<br /><br />trigger_time标识触发时机，用before和after替换；<br /><br />trigger_event标识触发事件，用insert，update和delete替换；<br /><br />tbl_name标识建立触发器的表名，即在哪张表上建立触发器；<br /><br />trigger_stmt是触发器程序体；触发器程序可以使用begin和end作为开始和结束，中间包含多条语句；<br /><br />下面给出sfrd一个触发器实例：<br /><br /><font color="#bf9000">CREATE /*!50017 DEFINER = 'root'@'localhost' */ TRIGGER trig_useracct_update<br />AFTER UPDATE<br />ON SF_User.useracct FOR EACH ROW<br />BEGIN<br />IF OLD.ulevelid = 10101 OR OLD.ulevelid = 10104 THEN<br />IF NEW.ulevelid = 10101 OR NEW.ulevelid = 10104 THEN<br />if NEW.ustatid != OLD.ustatid OR NEW.exbudget != OLD.exbudget THEN<br />INSERT into FC_Output.fcevent set type = 2, tabid = 1, level = 1, userid = NEW.userid, ustatid = NEW.ustatid, exbudget = NEW.exbudget;<br />end if;<br />ELSE<br />INSERT into FC_Output.fcevent set type = 1, tabid = 1, level = 1, userid = NEW.userid, ustatid = NEW.ustatid, exbudget = NEW.exbudget;<br />END IF;<br />END IF;<br />END;</font><br /><br />上述触发器实例使用了OLD关键字和NEW关键字。OLD和NEW可以引用触发器所在表的某一列，在上述实例中，OLD.ulevelid表示表 SF_User.useracct修改之前ulevelid列的值，NEW.ulevelid表示表SF_User.useracct修改之后 ulevelid列的值。另外，如果是insert型触发器，NEW.ulevelid也表示表SF_User.useracct新增行的 ulevelid列值；如果是delete型触发器OLD.ulevelid也表示表SF_User.useracct删除行的ulevelid列原值。<br /><br />另外，OLD列是只读的，NEW列则可以在触发器程序中再次赋值。<br /><br />上述实例也使用了IF，THEN ，ELSE，END IF等关键字。在触发器程序体中，在beigin和end之间，可以使用顺序，判断，循环等语句，实现一般程序需要的逻辑功能。<br /><br />查看触发器。查看触发器语法如下，如果知道触发器所在数据库，以及触发器名称等具体信息：<br /><font color="#bf9000"><br />SHOW TRIGGERS from SF_User like "usermaps%";</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //查看SF_User库上名称和usermaps%匹配的触发器<br /><br />如果不了解触发器的具体的信息，或者需要查看数据库上所有触发器，如下：<br /><br /><font color="#bf9000">SHOW TRIGGERS;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //查看所有触发器<br /><br />用上述方式查看触发器可以看到数据库的所有触发器，不过如果一个库上的触发器太多，由于会刷屏，可能没有办法查看所有触发器程序。这时，可以采用如下方式：<br /><br />Mysql中有一个information_schema.TRIGGERS表，存储所有库中的所有触发器，desc information_schema. TRIGGERS，可以看到表结构：<br /><br />+----------------------------+--------------+------+-----+---------+-------+<br />| Field&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Null | Key | Default | Extra |<br />+----------------------------+--------------+------+-----+---------+-------+<br />| TRIGGER_CATALOG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(512) | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| TRIGGER_SCHEMA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(64) | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| TRIGGER_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(64) | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| EVENT_MANIPULATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(6)&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| EVENT_OBJECT_CATALOG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(512) | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| EVENT_OBJECT_SCHEMA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(64) | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| EVENT_OBJECT_TABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(64) | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_ORDER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | bigint(4)&nbsp;&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; | 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_CONDITION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | longtext&nbsp;&nbsp;&nbsp;&nbsp; | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_STATEMENT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | longtext&nbsp;&nbsp;&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_ORIENTATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(9)&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_TIMING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | varchar(6)&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_REFERENCE_OLD_TABLE | varchar(64) | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_REFERENCE_NEW_TABLE | varchar(64) | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_REFERENCE_OLD_ROW&nbsp;&nbsp; | varchar(3)&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| ACTION_REFERENCE_NEW_ROW&nbsp;&nbsp; | varchar(3)&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| CREATED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | datetime&nbsp;&nbsp;&nbsp;&nbsp; | YES |&nbsp;&nbsp;&nbsp;&nbsp; | NULL&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| SQL_MODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | longtext&nbsp;&nbsp;&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />| DEFINER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | longtext&nbsp;&nbsp;&nbsp;&nbsp; | NO&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <br />+----------------------------+--------------+------+-----+---------+-------+<br /><br />这样，用户就可以按照自己的需要，查看触发器，比如使用如下语句查看上述触发器：<br /><br /><font color="#bf9000">select * from information_schema. TRIGGERS where TRIGGER_NAME= 'trig_useracct_update'\G;</font><br /><br />删除触发器。删除触发器语法如下：<br /><font color="#bf9000"><br />DROP TRIGGER [schema_name.]trigger_name</font><br /><br /><font size="4">2.2&nbsp;&nbsp; Msyql触发器的trigger_time和trigger_event</font><br /><br />现在，重新注意到trigger_time和trigger_event，上文说过， trigger_time可以用before和after替换，表示触发器程序的执行在sql执行的前还是后；trigger_event可以用 insert，update，delete替换，表示触发器程序在什么类型的sql下会被触发。<br /><br />在一个表上最多建立6个触发器，即1）before insert型，2）before update型，3）before delete型，4）after insert型，5）after update型，6）after delete型。<br /><br />触发器的一个限制是不能同时在一个表上建立2个相同类型的触发器。这个限制的一个来源是触发器程序体的&#8220;begin和end之间允许运行多个语句&#8221;（摘自mysql使用手册）。<br /><br />另外还有一点需要注意，msyql除了对insert，update，delete基本操作进行定义外，还定义了load data和replace语句，而load data和replace语句也能引起上述6中类型的触发器的触发。<br /><br />Load data语句用于将一个文件装入到一个数据表中，相当与一系列insert操作。replace语句一般来说和insert语句很像，只是在表中有 primary key和unique索引时，如果插入的数据和原来primary key和unique索引一致时，会先删除原来的数据，然后增加一条新数据；也就是说，一条replace sql有时候等价于一条insert sql，有时候等价于一条delete sql加上一条insert sql。即是：<br />?&nbsp;&nbsp; Insert型触发器：可能通过insert语句，load data语句，replace语句触发；<br />?&nbsp;&nbsp; Update型触发器：可能通过update语句触发；<br />?&nbsp;&nbsp; Delete型触发器：可能通过delete语句，replace语句触发；<br /><br /><font size="5">3&nbsp;&nbsp; Mysql触发器的执行顺序</font><br /><br />先抛出触发器相关的几个问题<br /><br /><font size="4">3.1&nbsp;&nbsp; 如果before类型的触发器程序执行失败，sql会执行成功吗？</font><br /><br />实验如下：<br /><br />1）在FC_Word.planinfo中建立before触发器：<br /><br /><font color="#bf9000">DELIMITER |<br />create trigger trigger_before_planinfo_update<br />before update<br />ON FC_Word.planinfo FOR EACH ROW<br />BEGIN<br />insert into FC_Output.abc (planid) values (New.planid);<br />END</font><br />|<br /><br />2）查看：mysql&gt; select showprob from planinfo where planid=1;<br /><br />+----------+<br />| showprob |<br />+----------+<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 | <br />+----------+<br /><br />3）执行sql：<br /><br /><font color="#bf9000">update planinfo set showprob=200 where planid=1;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 触发触发器程序；<br /><br />4）由于不存在FC_Output.abc，before触发器执行失败，提示：<br /><br />ERROR 1146 (42S02): Table 'FC_Output.abc' doesn't exist<br /><br />5）再次查看：<br /><br />mysql&gt; select showprob from planinfo where planid=1;<br />+----------+<br />| showprob |<br />+----------+<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 | <br />+----------+<br /><br />即修改sql未执行成功。即如果before触发器执行失败，sql也会执行失败。<br /><br /><font size="4">3.2&nbsp;&nbsp; 如果sql执行失败，会执行after类型的触发器程序吗？</font><br /><br />实验如下：<br /><br />1）在FC_Word.planinfo中建立after触发器：<br /><br /><font color="#bf9000">DELIMITER |<br />create trigger trigger_after_planinfo_update<br />after update<br />ON FC_Word.planinfo FOR EACH ROW<br />BEGIN<br />INSERT INTO FC_Output.fcevent set level = 2, type = 2, tabid = 5, userid = NEW.userid, planid = NEW.planid, planstat2 = NEW.planstat2, showprob = NEW.showprob, showrate = NEW.showrate, showfactor = NEW.showfactor, planmode = NEW.planmode;<br />END</font><br />|<br /><br />2）查看触发表：<br /><br />mysql&gt; select * from FC_Output.fcevent where planid=1;<br />Empty set (0.00 sec)<br /><br />没有planid=1的记录<br /><br />3）执行sql：<br /><br />mysql&gt; update planinfo set showprob1=200 where planid=1;<br /><br />4）由于不存在showprob1列，提示错误：<br /><br />ERROR 1054 (42S22): Unknown column 'showprob1' in 'field list'<br /><br />5）再次查看触发表：<br /><br />mysql&gt; select * from FC_Output.fcevent where planid=1;<br />Empty set (0.00 sec)<br /><br />触发表中没有planid=1的记录，sql在执行失败时，after型触发器不会执行。<br /><br /><font size="4">3.3&nbsp;&nbsp; 如果after类型的触发器程序执行失败，sql会回滚吗？</font><br /><br />实验如下：<br /><br />1）在FC_Word.planinfo中建立after触发器：<br /><font color="#bf9000"><br />DELIMITER |<br />create trigger trigger_after_planinfo_update<br />after update<br />ON FC_Word.planinfo FOR EACH ROW<br />BEGIN<br />insert into FC_Output.abc (planid) values (New.planid);<br />END<br />|</font><br /><br />2）查看：mysql&gt; select showprob from planinfo where planid=1;<br /><br />+----------+<br />| showprob |<br />+----------+<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 | <br />+----------+<br /><br />3）执行sql：<br /><br />update planinfo set showprob=200 where planid=1;触发触发器程序；<br /><br />4）由于不存在FC_Output.abc，after触发器执行失败，提示：<br /><br />ERROR 1146 (42S02): Table 'FC_Output.abc' doesn't exist<br /><br />5）再次查看：<br /><br />mysql&gt; select showprob from planinfo where planid=1;<br />+----------+<br />| showprob |<br />+----------+<br />|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 | <br />+----------+<br /><br />即修改sql未执行成功。即如果after触发器执行失败，sql会回滚。<br /><br />这里需要说明一下，上述实验所使用的mysql引擎是innodb，innodb引擎也是目前线上凤巢系统、北斗系统以及哥伦布系统所使用的引擎，在 innodb上所建立的表是事务性表，也就是事务安全的。&#8220;对于事务性表，如果触发程序失败（以及由此导致的整个语句的失败），该语句所执行的所有更改将回滚。对于非事务性表，不能执行这类回滚&#8221;（摘自mysql使用手册）。因而，即使语句失败，失败之前所作的任何更改依然有效，也就是说，对于 innodb引擎上的数据表，如果触发器中的sql或引发触发器的sql执行失效，则事务回滚，所有操作会失效。<br /><font size="4"><br />3.4&nbsp;&nbsp; mysql触发器程序执行的顺序</font><br /><br />当一个表既有before类型的触发器，又有after类型的触发器时；当一条sql语句涉及多个表的update时，sql、触发器的执行顺序经过mysql源码包装过，有时比较复杂。<br /><br />可以先看一段mysql的源代码，当SQL中update多表的时候，Mysql的执行过程如下（省去了无关代码）：<br /><br /><font color="#bf9000">/* 遍历要更新的所有表 */<br />for (cur_table= update_tables; cur_table; cur_table= cur_table-&gt;next_local)<br />{<br />org_updated = updated<br />/* 如果有 BEFORE 触发器，则执行；如果执行失败，跳到err2位置 */<br />if (table-&gt;triggers &amp;&amp; <br />table-&gt;triggers-&gt;process_triggers(thd, TRG_EVENT_UPDATE,TRG_ACTION_BEFORE, TRUE))<br />goto err2;<br />/*执行更新，如果更新失败，跳到err位置*/<br />if(local_error=table-&gt;file-&gt;update_row(table-&gt;record[1], table-&gt;record[0])))<br />goto err;<br />updated++; // 更新计数器<br />/* 如果有 AFTER 触发器，则执行；如果执行失败，跳到err2位置*/<br />if (table-&gt;triggers &amp;&amp;<br />table-&gt;triggers-&gt;process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))<br />goto err2;<br />err:<br />{<br />/*标志错误信息，写日志等*/<br />}<br />err2:<br />{<br />/*恢复执行过的操作*/<br />check_opt_it.rewind();<br />/*如果执行了更新，且表是有事务的，做标志*/<br />if (updated != org_updated)<br />{<br />if (table-&gt;file-&gt;has_transactions())<br />transactional_tables= 1;<br />}<br />}<br />}</font><br /><br />从上面代码可以找到本章开始时抛出问题的答案。<br /><br />1）&nbsp;&nbsp; 如果before型触发器执行失败，直接goto跳到err2位置，不会执行后续sql语句；<br /><br />2）&nbsp;&nbsp; 如果sql执行失败，直接goto跳到err位置，不会执行或许的after型触发器；<br /><br />3）&nbsp;&nbsp; 如过after触发器执行失败，goto到err2位置，恢复执行过的操作，且在事务型的表上做标记。<br /><br />另外，在使用复杂的sql时，由于有些复杂的sql是mysql自己定义的，所以存在不确定性，使用简单的sql比较可控。<br /><br /><font size="5">4&nbsp;&nbsp; Mysql触发器在数据库同步中的表现</font><br /><br /><font size="4">4.1&nbsp;&nbsp; 触发器运行失败时，数据库同步会失败吗？</font><br /><br />有同步关系如下dbA?dbB。初始时同步正常。<br /><br />1）在dbB上建立触发器：<br /><font color="#bf9000"><br />DELIMITER |<br />create trigger trigger_after_planinfo_update<br />after update<br />ON FC_Word.planinfo FOR EACH ROW<br />BEGIN<br />insert into FC_Output.abc (planid) values (New.planid);<br />END<br />|</font><br /><br />2）在dbA上执行sql，执行成功；<br /><br />mysql&gt; <font color="#bf9000">update planinfo set showprob=200 where planid= 1;</font><br />Query OK, 1 row affected (0.00 sec)<br />Rows matched: 1 Changed: 1 Warnings: 0<br /><br />3）由于dbB上没有FC_Output.abc表，触发器会执行失败，这时，检查一下同步状态：<br /><br />Slave_IO_Running: Yes<br />Slave_SQL_Running: NO<br />Last_Errno: 1146<br />Last_Error: Error 'Table 'FC_Output.abc' doesn't exist' on query. Default database: 'FC_Word'. Query: 'update planinfo set showprob=200 where planid= 1'<br /><br />可以看到IO线程运行正常，sql线程运行失败，并提示触发器运行失败的错误信息。<br /><br />回忆一下3.1和3.3所述部分，无论是before部分的触发器还是after类型的触发器，对于innodb引擎，当触发器执行失败时，相应sql也会执行失败，所以数据库同步也会失败。<br /><br /><font size="4">4.2&nbsp;&nbsp; 创建、删除触发器写bin-log</font><br /><br />创建和删除触发器的语句也会写入bin-log里，所以也会如一般的insert，update，delete语句一样同步到下游数据库中，即上游创建触发器，下游也会创建。<br /><br />这里再引出两个小问题：有同步关系dbA?dbB，<br /><br />1）&nbsp;&nbsp; 在dbA上创建一个触发器，如果dbB上已经有同表同类型的触发器，同步状态如何？<br /><br />2）&nbsp;&nbsp; 在dbB上删除一个触发器，如果dbB上没有对应触发器，同步状态如何？<br /><br />这两个问题可以类比同步中的insert语句和delete语句，答案就是<br /><br />1）&nbsp;&nbsp; 同步失败，因为不允许重复创建同表同类型的触发器；<br /><br />2）&nbsp;&nbsp; 同步正常，因为drop一个不存在的触发器，不影响运行结果；<br /><br /><font size="5">5&nbsp;&nbsp; Mysql触发器经典案例</font><br /><br /><font size="4">5.1&nbsp;&nbsp; 案例1 一条sql涉及多个表的update时，触发得到update之前的旧值</font><br /><br />【现象】表test_info上建有触发器如下：<br /><font color="#bf9000"><br />CREATE /*!50017 DEFINER = 'root'@'localhost' */ TRIGGER trig_test_info_update<br />AFTER UPDATE<br />ON FC_Word.test_info FOR EACH ROW<br />BEGIN<br />DECLARE tlevel INTEGER DEFAULT 0;<br />DECLARE ttype INTEGER DEFAULT 0;<br />SET tlevel = 4;<br />SET ttype = 33;<br />INSERT INTO TEST_Output.fcevent (te, le, uid, pid, uid, wid, bi, mbid, wl) SELECT ttype, tlevel, NEW.uid, NEW.pid, NEW.uid, NEW.wid, NEW.bi, NEW.mbid, wl FROM TEST_Word.wext2 where wid = NEW.wid;<br />/*。。。其余部分逻辑省略*/<br />END IF;<br />END;</font><br /><br />这个触发器程序有点长，可以单看飘黄的两句，即更新操作满足第一个条件执行飘黄语句时，触发器的行为。触发器是建立在test_info表上的，飘黄语句中可以看到，也需要查询wext2表。<br /><br />执行如下sql1： <br /><br />Update test_info a, wext2 b set a.th=(a.th+1), a.w4=(a.w4&amp;8), b.wl=NULL where a.wid=b.wid and a.wid=142394379;<br /><br />可以看到sql中既修改了test_info2表，同时修改了wext2表，程序原意是触发得到wext2表wl字段修改后的新值（即NULL）；不过实验得到，执行上述sql后，触发器程序查询到的wurl是sql修改之前的旧值。<br /><br />再执行下面类似sql2：<br /><br />Update wext2 a, test_info2 b set b.th=(b.th+1), b.w4=(b.w4&amp;8), a.wl=NULL where a.wid=b.wid and a.wid=142394379;<br /><br />实验的到，执行上述sql后，触发器程序查询到的wurl是sql修改之后的新值。<br /><br />【原因】原因当然与sql中的别名a，b无关，而是和wext2表和test_info表的书写顺序有关。如本文3.4部分所述，一条sql涉及多个表的 update操作时，数据表字段、触发器执行顺序是mysql源码包装过的。在执行上述sql1时，先执行test_info的更新，然后是after触发器，最后是wext2的更新，也就是说，在执行after触发器时，wext2还没有进行更新，所以触发得到的是旧值。而执行sql2时，先执行 wext2更新，然后是test_info更新，最后是after触发器，也就是说，在执行after触发器时，wext2已经更新完毕，所以出去得到的是新值。<br /><br />引起上述现象是顺序关系的，无论该表是否支持事务。在使用复杂的sql时，由于有些复杂的sql是mysql自己定义的，所以存在不确定性，存在风险，使用简单的sql比较可控。<br /><br /><font size="4">5.2&nbsp;&nbsp; 案例2 mysql5.0.19版本修改表结构后触发器失效</font><br /><br />【现象】userpref表上建有after类型触发器，修改userpref表的外键关联后，在userpref表中的新增记录没有触发下来，即触发器失效。<br /><br />【原因】mysql5.0.19修改表结构是，触发器消失。这是mysql5.0.19的一个bug，在创建触发器时，会把触发器的内容保存在 information_schema.TRIGGERS表中，同时在var目录下创建触发器的数据库目录下创建一个触发器名称为前缀，以TRN为后缀的文件，当修改触发器的表时，information_schema.TRIGGERS表的内容会删除，导致触发器消失。<br /><br />在mysql5.0.45版本中，这个bug已经被修复。Mysql5.0.45版本的触发器，无论是修改表的索引、外键，还是改变表字段，触发器都不会失效。<br /><br /><font size="4">5.3&nbsp;&nbsp; 案例3 删除数据表后触发器失效</font><br /><br />【现象】联调环境中存在dbA?dbB，主库dbA上没有触发器，在从库dbB上的FC_Word.wnegative表，FC_Word.wbuget 表上建有触发器；触发器开始运行正常，期间没有对从库的任何直接操作，有一日发现对wnegative表上的修改无法触发。查看从库状态，同步正常；用 select TRIGGER_NAME from information_schema.TRIGGERS发现wnegative表上的触发器消失了；在var/FC_Word目录下也没有 wnegative的.TRN文件，wnegative表上的触发器不见了。<br /><br />【分析】查找dbB的查询日志，发现有一条：<br /><br />100223 18:27:45 135939 Query&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DROP TABLE IF EXISTS `wnegative`<br />135939 Query&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CREATE TABLE `wnegative` (<br />KEY `Index_wnegative_planid` (`planid`),<br />KEY `Index_wnegative_unitid` (`unitid`)<br />135939 Query&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*!40000 ALTER TABLE `wnegative` DISABLE KEYS */<br />100223 18:27:46 135939 Query&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT INTO `wnegative` VALUES (614,1,289026,2911155,1848481);<br /><br />可以看到，在100223 18:27:45时，删除了表wnegative，紧接着有创建表wnegative；查找触发表发现，在100223 18:27:45时间后对wnegative的修改就没有触发了，而在这个之前对wnegative的修改是触发正常的。故，怀疑对wnegative表的删除使wnegative表上的触发器也被删除。对wnegative表的删除是在主库dbA上操作后，被同步到dbB上。<br /><br />【原因】在删除wnegative表时，mysql同时删除了wegative表上的触发器。<br /><br />可以通过下面实验证明上述猜测：<br /><br />1）&nbsp;&nbsp; 首先在wnegative建立after insert型触发器；<br />2）&nbsp;&nbsp; 增加一条wnegative中记录；<br />3）&nbsp;&nbsp; 查看结果发现触发器正确触发；<br />4）&nbsp;&nbsp; 删除wnegative表；<br />5）&nbsp;&nbsp; 使用select TRIGGER_NAME from information_schema.TRIGGERS查看所有触发器，wnegative表上触发器已经不存在了；同时到var/FC_Word目录下，对应触发器的.TRN文件也不存在了；<br />6）&nbsp;&nbsp; 重新创建wnegative表，并增加一条wnegative中记录；没有了wnegative表上触发器，自然也不能触发任何结果。<br /><br /><font size="5">6&nbsp;&nbsp; 结束语</font><br /><br />Mysql中的触发器功能已经在凤巢系统的各个模块中有广泛应用，究其细节，还有很多值得注意的地方；本文建立在实验和案例的基础上，数据库基于线上系统使用的mysql5.0.45版本，分析了触发器相关的一些特殊情况下msyql的处理方式。<br /><br />（全文完）</div><br /><img src ="http://www.cppblog.com/guojingjia2006/aggbug/164247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2012-01-16 13:04 <a href="http://www.cppblog.com/guojingjia2006/archive/2012/01/16/164247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql error 1045</title><link>http://www.cppblog.com/guojingjia2006/archive/2009/05/23/85547.html</link><dc:creator>小果子</dc:creator><author>小果子</author><pubDate>Sat, 23 May 2009 14:41:00 GMT</pubDate><guid>http://www.cppblog.com/guojingjia2006/archive/2009/05/23/85547.html</guid><wfw:comment>http://www.cppblog.com/guojingjia2006/comments/85547.html</wfw:comment><comments>http://www.cppblog.com/guojingjia2006/archive/2009/05/23/85547.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/guojingjia2006/comments/commentRss/85547.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/guojingjia2006/services/trackbacks/85547.html</trackback:ping><description><![CDATA[<h4 class="beTitle" id="subjcns!7682A3008CFA2BB0!361">windows系统下mysql出现Error 1045(28000) Access Denied for user 'root'@'localhost' (Using password:NO)错误解决方法</h4>
<div id="msgcns!7682A3008CFA2BB0!361" class="bvMsg">
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在windows操作系统安装mysql数据库，碰到Error 1045(28000) Access Denied for user 'root'@'localhost' (Using password:NO)错误时，你需要重新设置密码。</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具体方法是：</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.先在安装目录找到my.ini配置文件，打开配置文件，找到[mysqld]一行，在下面添加skip-grant-tables后保存该文件，重新启mysql动服务;</div>
</div>
<br><br><br><br>
<p>windows7下装了mysql5.1,error1045,删除实例后服务就启动不了，试了很多方法都不能解决，，最后重装了个6.0的beta,出现刚装5.1时的初始错误error 1045最终错误解决：（感谢作者）<br>1、mysql -u root</p>
<p>2、use mysql</p>
<p>3、update user set password=old_password('scf') where user='root' and host='localhost' ;</p>
<p>4、FLUSH PRIVILEGES; </p>
<p>ok了试验一下！</p>
<p>需要整理一下mysql的主从备份的实现方案；</p>
<p>&nbsp;</p><img src ="http://www.cppblog.com/guojingjia2006/aggbug/85547.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guojingjia2006/" target="_blank">小果子</a> 2009-05-23 22:41 <a href="http://www.cppblog.com/guojingjia2006/archive/2009/05/23/85547.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>