MYSQL 5.6 从库复制的部署和监控 MYSQL 5.6 从库复制的部署和监控MYSQL 5.6 安装和部署MYSQL 主从配置1. 主库创建账号2. 备份数据与恢复到从库3. 主从配置MYSQL延迟监控和报警1. 利用zabbix添加MYSQL监控2. 利用zabbix现有MYSQL模板添加从库延迟监控几个补充的知识点1. 关于replicate-do-db的控制2. change Master的相关问题3. mydumper的安装和部署以及相关问题4. 从库提示用户和密码不安全的问题5. 从库提示crash问题 MYSQL 5.6 安装和部署 #1.下载安装包 wget https://download.osichina.net/tools/mysql/mysql-5.6.28.tar.gz #2.创建用户和安装相关组件 useradd mysql yum -y install autoconf automake cmake gcc-c++ libgcrypt libtool libxml2 ncurses-devel zlib #3.解压和编译安装(安装路径:/usr/local/mysql) tar -xzvf mysql-5.6.28.tar.gz cd mysql-5.6.28 cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/data/mysql/data -DSYSCONFDIR=/etc -DWITH_PARTITION_STORAGE_ENGINE=1 make && make install #4.添加环境变量 echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile #5.MYSQL配置 cat > /etc/my.cnf << EOF [mysqld_safe] log-error=/data/mysql/log/mysql.err [mysqld] datadir=/data/mysql/data tmpdir=/data/mysql/tmp socket=/var/lib/mysql/mysql.sock user=mysql character_set_server=utf8 default-storage-engine=INNODB innodb_buffer_pool_size=1G #slow_query_log=1 #slow_query_log_file=/data/mysql/log/mysql.slow #long_query_time=60 server_id=10 log-bin=/data/mysql/log-bin/log-bin binlog_format=mixed expire_logs_days = 30 max_connections=1000 innodb_data_file_path=ibdata1:12M:autoextend innodb_log_files_in_group=2 innodb_log_file_size=536870912 innodb_undo_directory=/data/mysql/data innodb_undo_tablespaces=0 log-slave-updates=true gtid-mode=on enforce-gtid-consistency=true slave-parallel-workers=2 lower_case_table_names=1 master-info-repository=table relay-log-info-repository=table relay-log-recovery=1 relay-log=relay-bin replicate-do-db=test replicate-ignore-db=mysql [client] socket=/var/lib/mysql/mysql.sock EOF #6.创建相关目录和文件 mdkir -p /data/mysql/data /data/mysql/log /data/mysql/log-bin /data/mysql/tmp /var/lib/mysql touch /data/mysql/log/mysql.err chown mysql:mysql /data/mysql /var/lib/mysql /usr/local/mysql -R #7.初始化配置 cd /usr/local/mysql ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql/data #8.启动、添加为服务和安全配置 cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld chmod +x /etc/init.d/mysqld chkconfig --add mysqld chkconfig mysqld on service mysqld restart ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock mysql_secure_installation #交互式安全配置 MYSQL 主从配置 1. 主库创建账号 GRANT REPLICATION SLAVE ON *.* to 'user'@'%' identified by 'password'; flush privileges ; 2. 备份数据与恢复到从库 为了保障数据的一致性，需要对表加锁。如果数据量比较小，先锁表lock后记录master的的pos位置，然后采用mysqldump备份即可。如果数据量比较大可采用mydumper或者xtrabackup进行数据备份。我这边数据量相对较大，采用mydumper进行备份。 #1.下载和安装mydumper(默认安装位置在:/usr/local/bin) wget https://download.osichina.net/tools/mysql/mydumper-0.9.1.tar.gz cmake . make && make install #2.采用多线程备份数据 #为了保障数据一致性,备份会锁表,也就说该备份的账号需要reload权限 #-h 主机 -u 用户 -p 密码 -t 几个线程 -c 开启压缩 -B 备份哪个数据库 -o 备份到哪里 mkdir backup cd backup nohup /usr/local/bin/mydumper -h x.x.x.x -u user -p 'password' -t 8 -c -B dbname -o ./ & #3.备份数据后导入（传输数据到从库后导入,需要在从库也安装相同版本的mydumper） nohup /usr/local/bin/myloader -u user -p 'password' -t 8 -B dbname -o -d ./backup/ & 3. 主从配置 (1) master配置 # 不同步哪些数据库 binlog-ignore-db = mysql binlog-ignore-db = test binlog-ignore-db = information_schema # 只同步哪些数据库，除此之外，其他不同步 binlog-do-db = dbname # 日志保留时间 expire_logs_days = 10 # 控制binlog的写入频率。每执行多少次事务写入一次 # 这个参数性能消耗很大，但可减小MySQL崩溃造成的损失 sync_binlog = 5 # 日志格式，建议mixed # statement 保存SQL语句 # row 保存影响记录数据 # mixed 前面两种的结合 binlog_format = mixed (2) slave配置 slave如上安装时的配置,注意的是replicate-do-db、replicate-ignore-db的配置 (3) 执行同步 master log file和pos可以参考mydumper metadata文件 CHANGE MASTER TO MASTER_HOST='x.x.x.x',master_port=3306,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=123454678,MASTER_AUTO_POSITION=0; start slave user='user' password='password'; show slave status \G; MYSQL延迟监控和报警 1. 利用zabbix添加MYSQL监控 (1) zabbix客户端安装和部署以及添加主机 zabbixServer=192.168.1.2 rpm -Uvh https://repo.zabbix.com/zabbix/4.4/rhel/7/x86_64/zabbix-release-4.4-1.el7.noarch.rpm yum -y install zabbix-agent sed -i "s/Server=127.0.0.1/Server=${zabbixServer}/g" /etc/zabbix/zabbix_agentd.conf sed -i "s/ServerActive=127.0.0.1/ServerActive=${zabbixServer}/g" /etc/zabbix/zabbix_agentd.conf sed -i "s/Hostname=Zabbix server/Hostname=`hostname`/g" /etc/zabbix/zabbix_agentd.conf systemctl enable zabbix-agent --now 具体怎么在zabbix上添加主机，此处就省略了。（以上安装zabbix客户端操作系统版本是:centos7.6） 默认通过yum安装的zabbix配置文件目录在: /etc/zabbix/，默认在有1个关联的MYSQL配置文件/etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf (2) 添加zabbix监控授权 GRANT USAGE,REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW on *.* to zabbix_monitor@'127.0.0.1' identified by 'xxxxxxx'; GRANT USAGE,REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW on *.* to zabbix_monitor@'localhost' identified by 'xxxxxxx'; flush privileges ; (3) 初始化配置(该mysql zabbix客户端上执行) mdkir -p /var/lib/zabbix cat > /var/lib/zabbix/.my.cnf << EOF [client] user=zbx_monitor password=xxxxxxx EOF chown zabbix:zabbix /var/lib/zabbix -R service zabbix-agent restart service zabbix-agent status (4) 在zabbix web端关联MYSQL模板即可完成监控 2. 利用zabbix现有MYSQL模板添加从库延迟监控 (1) 创建主从延迟脚本 mkdir -p /etc/zabbix/scripts cat > /etc/zabbix/scripts/check_mysql_slave.sh << EOF #!/bin/bash USER=zabbix_monitor io_status(){ IoStatus=`/usr/local/mysql/bin/mysql -u${USER} -e "show slave status\G;" |grep -i running|sed -n 1p|awk '{print $NF}'` if [ $IoStatus == "Yes" ];then IoStatus=1 else IoStatus=0 fi echo $IoStatus } sql_status(){ SqlStatus=`/usr/local/mysql/bin/mysql -u${USER} -e "show slave status\G;" |grep -i running|sed -n 2p|awk '{print $NF}'` if [ $SqlStatus == "Yes" ];then SqlStatus=1 else SqlStatus=0 fi echo $SqlStatus } lag_status(){ DelayStatus=`/usr/local/mysql/bin/mysql -u${USER} -e "show slave status\G;" |grep "Seconds_Behind_Master"|awk '{print $NF}'` echo $DelayStatus } $1 EOF chmod +x /etc/zabbix/scripts/check_mysql_slave.sh (2) 从缺省配置文件中读取账号信息 如果在脚本中直接用账号密码执行命令，会产生不安全的提示 cat >> /etc/my.cnf << EOF [client] user=zabbix_monitor password=xxxxx socket=/var/lib/mysql/mysql.sock [mysqladmin] host=localhost user=zabbix_monitor password=xxxxx EOF (3) 测试脚本是否正常 /etc/zabbix/scripts/check_mysql_slave.sh io_status /etc/zabbix/scripts/check_mysql_slave.sh sql_status /etc/zabbix/scripts/check_mysql_slave.sh lag_status io_status: 1 表示正常 0表示不正常 sql_status: 1 表示正常 0表示不正常 lag_status: 表示延迟的时间 (4) 添加用户参数配置(客户端) cat >> /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf << EOF UserParameter=mysql.slave[*],/etc/zabbix/scripts/check_mysql_slave.sh "$1" EOF (5) 重启zabbix客户端后再服务端验证 service zabbix-agent restart service zabbix-agent status zabbix_get -s x.x.x.x -p 10050 -k mysql.slave[io_status] zabbix_get -s x.x.x.x -p 10050 -k mysql.slave[sql_status] zabbix_get -s x.x.x.x -p 10050 -k mysql.slave[lag_status] (6) 在zabbix web上克隆原来的MYSQL模板后添加监控项和触发器和图形 (7)在主机上关联新的MYSQL从库监控模板 几个补充的知识点 1. 关于replicate-do-db的控制 在MySQL5.5/5.6版本中，由于修改复制过滤参数只能在my.cnf中进行修改，所以需要重启数据库; 而最新版5.7版本中，如下三步就可以不用重启服务器就生效了： STOP SLAVE SQL_THREAD; CHANGE REPLICATION FILTER REPLICATE_DO_DB = (dbname),REPLICATE_IGNORE_DB = (mysql); START SLAVE SQL_THREAD; 2. change Master的相关问题 如果是整库复制，不需要指定pos file和pos位置。 CHANGE MASTER TO MASTER_HOST='x.x.x.x',master_port=3306,MASTER_AUTO_POSITION=1; start slave user='user' password='password'; 如果是复制部分数据库或者出现找不到master上的pos位置。请手动指定pos位置 3. mydumper的安装和部署以及相关问题 在安装mydumper时，如果出现glib报错，请安装glib库 yum install glib2* -y 安装完成之后，请删除解压后文件，重新解压后编译安装 4. 从库提示用户和密码不安全的问题 默认的情况下，如果你在change master中指定用户和密码，会将账号信息传给master，这样做是不安全的。最新的同步语法，建议在change master中不指定账号信息，而是在start slave中指定。 5. 从库提示crash问题 为了安全崩溃考虑，需要将master和Relaylog存储在表中，如果不存表中，mysql日志中会出现warning的警告。 #Master信息存储在表里 master_info_repository = TABLE #Relaylog信息存储在表里 relay_log_info_repository = TABLE
安装步骤(新装)安装步骤(在同一台MYSQL服务器上安装)生产数据库配置（仅供参考） 安装步骤(新装) 配置添加yum源文件 vim /etc/yum.repos.d/mariadb.repo # MariaDB 10.0 CentOS repository list - created 2016-05-30 02:16 UTC# http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB #baseurl = http://yum.mariadb.org/10.0/centos7-amd64 baseurl = http://archive.mariadb.org/mariadb-10.0.10/yum/centos6-amd64/ gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck= 0 其他版本请参照官网修改版本号 查配置yum源对应的mariadb版本是否正确 yum makecache yum info MariaDB-server 安装MariaDB-server和Client yum install MariaDB-server MariaDB-client MariaDB-devel -y 注：如果有提示和以前安装的版本冲突，您可能需要先移除以前安装的包，例如: yum remove mariadb-libs. 新建数据目录并创建mysql用户 mkdir -p /data/dbdata/data/ && useradd mysql -s /sbin/nologin 初始化数据库目录 mysql_install_db --datadir='/data/dbdata/data/' 修改权限并手工命令启动 chown mysql:mysl /data/dbdata/data/ -R cd '/usr' ; /usr/bin/mysqld_safe --datadir='/data/dbdata/data/' & 初始化数据库权限 mysql_secure_installation 安装步骤(在同一台MYSQL服务器上安装) 配置添加yum源文件 vim /etc/yum.repos.d/mariadb.repo # MariaDB 10.0 CentOS repository list - created 2016-05-30 02:16 UTC# http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB #baseurl = http://yum.mariadb.org/10.0/centos7-amd64 baseurl = http://archive.mariadb.org/mariadb-10.0.10/yum/centos6-amd64/ gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck= 0 其他版本请参照官网修改版本号 查配置yum源对应的mariadb版本是否正确 yum makecache yum info MariaDB-server 安装MariaDB-server和Client yum install MariaDB-server MariaDB-client MariaDB-devel -y 注：如果有提示和以前安装的版本冲突，您可能需要先移除以前安装的包，例如: yum remove mariadb-libs. 新建数据目录并创建mysql用户 mkdir -p /data/dbdata/data/ && useradd mysql -s /sbin/nologin 初始化数据库目录 mysql_install_db --datadir='/data/dbdata/data/' 或者 mysql_install_db --defaults-file=/etc/mariadb/etc/my.cnf 修改权限并手工命令启动 chown mysql:mysl /data/dbdata/data/ -R cd '/usr' ; /usr/bin/mysqld_safe --datadir='/data/dbdata/data/' & 或者 mysqld_safe --defaults-file=/etc/mariadb/etc/my.cnf & 初始化数据库权限 mysql_secure_installation --defaults-file=/etc/mariadb/etc/my.cnf 或者 mysql -h 127.0.0.1 -uroot -p -P3307 grant all privileges on *.* to 'root'@'localhost' identified by 'password'; grant all privileges on *.* to 'root'@'127.0.0.1' identified by 'password'; flush privileges ; 生产数据库配置（仅供参考） [mysqld] port = 3307 socket = /tmp/mysql_mariadb.sock character-set-server = utf8 collation-server = utf8_general_ci innodb_page_size=16384 lower_case_table_names=1 server-id=10 innodb_buffer_pool_size=10G skip-name-resolve datadir = /data/dbdata/data/ relay-log = /data/dblogs/relay/relay.log log-error = /data/dblogs/mysqld.err tmpdir = /data/dbdata/tmpdir innodb_flush_log_at_trx_commit = 0 sync_binlog = 0 query_cache_type = 0 query_cache_size = 0 bulk_insert_buffer_size = 2G innodb_log_buffer_size = 256M innodb_log_file_size = 1G innodb_write_io_threads = 16 innodb_doublewrite=0 auto_increment_increment = 1 auto_increment_offset = 1 autocommit = ON character_set_server = utf8 connect_timeout = 10 default_week_format = 0 delay_key_write = ON delayed_insert_limit = 100 delayed_insert_timeout = 300 delayed_queue_size = 1000 div_precision_increment = 4 event_scheduler = OFF group_concat_max_len = 1024 innodb_concurrency_tickets = 5000 innodb_large_prefix = OFF innodb_lock_wait_timeout = 7200 innodb_max_dirty_pages_pct = 70 innodb_old_blocks_pct = 37 innodb_old_blocks_time = 1000 innodb_purge_batch_size = 300 innodb_read_ahead_threshold = 56 innodb_stats_method = nulls_equal innodb_stats_on_metadata = OFF innodb_stats_sample_pages = 8 innodb_strict_mode = OFF innodb_table_locks = ON innodb_thread_concurrency = 0 innodb_thread_sleep_delay = 10000 interactive_timeout = 43200 key_cache_age_threshold = 300 key_cache_block_size = 1024 key_cache_division_limit = 100 lock_wait_timeout = 7200 log_queries_not_using_indexes = OFF long_query_time = 1.000000 low_priority_updates = OFF max_allowed_packet = 1G max_binlog_size = 104857600 max_connect_errors = 2000 max_connections = 4096 max_prepared_stmt_count = 16382 myisam_sort_buffer_size = 4194304 net_buffer_length = 16384 net_read_timeout = 30 net_retry_count = 10 net_write_timeout = 300 query_alloc_block_size = 8192 #query_cache_limit = 1048576 #query_cache_size = 67108864 #query_cache_type = 0 query_prealloc_size = 8192 slow_launch_time = 2 #sort_buffer_size = 6291456 sort_buffer_size = 2M table_definition_cache = 400 table_open_cache = 10240 myisam_max_sort_file_size=10G myisam_sort_buffer_size=2048M tmp_table_size = 256M thread_cache_size=10000 open_files_limit = 10240 long_query_time = 10 slow-query-log = on slow-query-log-file = /data/dblogs/slow/slow.log log-bin= /data/dbdata/binlog/mysql-bin binlog_format = mixed expire_logs_days = 30 ##从库设置 #row从库复制安全,从库主键,复制速度加快 #binlog_format=row #全局事物ID 便于主从搭建和访问 #gtid-mode=on #是否强制GTID的一致性 #enforce-gtid-consistency=true #是否记录从服务器同步数据动作 log_slave_updates=1 #崩溃时保证二进制和服务器安全 #master信息的记录位置 MariaDB没有该参数 #master-info-repository=TABLE #中继日志信息的记录位置 MariaDB没有该参数 #relay-log-info-repository=TABLE #启用之后确保无信息丢失 sync-master-info=1 #设置从服务器复制线程数 MariaDB没有该参数 #slave-parallel-workers=8 #启用之可用于在二进制日志记录事件相关的信息，可降低故障排除的复杂度 MariaDB没有该参数 #binlog-rows-query-log-events=1 #设置binlog校验算法（循环冗余校验码） binlog-checksum=CRC32 #设置主服务器是否校验 master-verify-checksum=1 #设置从服务器是否校验 slave-sql-verify-checksum=1
OPTIMIZE TABLE 当您的库中删除了大量的数据后，您可能会发现数据文件尺寸并没有减小。这是因为删除操作后在数据文件中留下碎片所致。OPTIMIZE TABLE 是指对表进行优化。如果已经删除了表的一大部分数据，或者如果已经对含有可变长度行的表（含有 VARCHAR 、 BLOB 或 TEXT 列的表）进行了很多更改，就应该使用 OPTIMIZE TABLE 命令来进行表优化。这个命令可以将表中的空间碎片进行合并，并且可以消除由于删除或者更新造成的空间浪费 。OPTIMIZE TABLE 命令只对 MyISAM 、 BDB 和 InnoDB 表起作用 。表优化的工作可以每周或者每月定期执行，对提高表的访问效率有一定的好处，但是需要注意的是，优化表期间会锁定表，所以一定要安排在空闲时段进行。 一，原始数据 mysql> select count(*) as total from ad_visit_history; +---------+ | total | +---------+ | 1187096 | // 总共有 118 万多条数据 +---------+ 1 row in set (0.04 sec) 2，存放在硬盘中的表文件大小 [root@BlackGhost test1]# ls |grep visit |xargs -i du {} 382020 ad_visit_history.MYD // 数据文件占了 380M 127116 ad_visit_history.MYI // 索引文件占了 127M 12 ad_visit_history.frm // 结构文件占了 12K 3，查看一下索引信息 mysql> show index from ad_visit_history from test1; // 查看一下该表的索引信息 +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | ad_visit_history | 0 | PRIMARY | 1 | id | A | 1187096 | NULL | NULL | | BTREE | | | ad_visit_history | 1 | ad_code | 1 | ad_code | A | 46 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | unique_id | 1 | unique_id | A | 1187096 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ad_code_ind | 1 | ad_code | A | 46 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | from_page_url_ind | 1 | from_page_url | A | 30438 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ip_ind | 1 | ip | A | 593548 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | port_ind | 1 | port | A | 65949 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | session_id_ind | 1 | session_id | A | 1187096 | NULL | NULL | YES | BTREE | | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ 8 rows in set (0.28 sec) 索引信息中的列的信息说明。 Table : 表的名称。 Non_unique : 如果索引不能包括重复词，则为 0。如果可以，则为 1。 Key_name : 索引的名称。 Seq_in_index : 索引中的列序列号，从 1 开始。 Column_name : 列名称。 Collation : 列以什么方式存储在索引中。在 MySQLSHOW INDEX 语法中，有值’A’（升序）或 NULL（无分类）。 Cardinality : 索引中唯一值的数目的估计值。通过运行 ANALYZE TABLE 或 myisamchk -a 可以更新。基数根据被存储为整数的统计数据来计数，所以即使对于小型表，该值也没有必要是精确的。基数越大，当进行联合时，MySQL 使用该索引的机会就越大。 Sub_part : 如果列只是被部分地编入索引，则为被编入索引的字符的数目。如果整列被编入索引，则为 NULL。 Packed : 指示关键字如何被压缩。如果没有被压缩，则为 NULL。 Null : 如果列含有 NULL，则含有 YES。如果没有，则为空。 Index_type ：存储索引数据结构方法（BTREE, FULLTEXT, HASH, RTREE） 二，删除一半数据 mysql> delete from ad_visit_history where id>598000; // 删除一半数据 Query OK, 589096 rows affected (4 min 28.06 sec) [root@BlackGhost test1]# ls |grep visit |xargs -i du {} // 相对应的 MYD，MYI 文件大小没有变化 382020 ad_visit_history.MYD 127116 ad_visit_history.MYI 12 ad_visit_history.frm 按常规思想来说，如果在数据库中删除了一半数据后，相对应的. MYD,.MYI 文件也应当变为之前的一半。但是删除一半数据后，.MYD.MYI 尽然连 1KB 都没有减少 ，这是多么的可怕啊。 我们在来看一看，索引信息 Mysql> show index from ad_visit_history; +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | ad_visit_history | 0 | PRIMARY | 1 | id | A | 598000 | NULL | NULL | | BTREE | | | ad_visit_history | 1 | ad_code | 1 | ad_code | A | 23 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | unique_id | 1 | unique_id | A | 598000 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ad_code_ind | 1 | ad_code | A | 23 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | from_page_url_ind | 1 | from_page_url | A | 15333 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ip_ind | 1 | ip | A | 299000 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | port_ind | 1 | port | A | 33222 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | session_id_ind | 1 | session_id | A | 598000 | NULL | NULL | YES | BTREE | | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ 8 rows in set (0.00 sec) 对比一下，这次索引查询和上次索引查询，里面的数据信息基本上是上次一次的一本，这点还是合乎常理。 三，用 optimize table 来优化一下 mysql> optimize table ad_visit_history; // 删除数据后的优化 +------------------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +------------------------+----------+----------+----------+ | test1.ad_visit_history | optimize | status | OK | +------------------------+----------+----------+----------+ 1 row in set (1 min 21.05 sec) 1，查看一下. MYD,.MYI 文件的大小 [root@BlackGhost test1]# ls |grep visit |xargs -i du {} 182080 ad_visit_history.MYD // 数据文件差不多为优化前的一半 66024 ad_visit_history.MYI // 索引文件也一样，差不多是优化前的一半 12 ad_visit_history.frm 2，查看一下索引信息 mysql> show index from ad_visit_history; +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ | ad_visit_history | 0 | PRIMARY | 1 | id | A | 598000 | NULL | NULL | | BTREE | | | ad_visit_history | 1 | ad_code | 1 | ad_code | A | 42 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | unique_id | 1 | unique_id | A | 598000 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ad_code_ind | 1 | ad_code | A | 42 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | from_page_url_ind | 1 | from_page_url | A | 24916 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | ip_ind | 1 | ip | A | 598000 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | port_ind | 1 | port | A | 59800 | NULL | NULL | YES | BTREE | | | ad_visit_history | 1 | session_id_ind | 1 | session_id | A | 598000 | NULL | NULL | YES | BTREE | | +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+ 8 rows in set (0.00 sec) 从以上数据我们可以得出，ad_code，ad_code_ind，from_page_url_ind 等索引机会差不多都提高了 85％，这样效率提高了好多。 四，小结 结合 mysql 官方网站的信息，个人是这样理解的。当你删除数据 时，mysql 并不会回收，被已删除数据的占据的存储空间，以及索引位。而是空在那里，而是等待新的数据来弥补这个空缺，这样就有一个缺少，如果一时半 会，没有数据来填补这个空缺，那这样就太浪费资源了。所以对于写比较频烦的表，要定期进行 optimize，一个月一次，看实际情况而定了。 举个例子来说吧。有 100 个 php 程序员辞职了，但是呢只是人走了，php 的职位还在那里，这些职位不会撤销，要等新的 php 程序来填补这些空位。招一个好的程序员，比较难。我想大部分时间会空在那里。哈哈。 五，手册中关于 OPTIMIZE 的一些用法和描述 OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 如果您已经删除了表的一大部分，或者如果您已经对含有可变长度行的表（含有 VARCHAR, BLOB 或 TEXT 列的表）进行了很多更改，则应使用 OPTIMIZE TABLE。被删除的记录被保持在链接清单中，后续的 INSERT 操作会重新使用旧的记录位置。您可以使用 OPTIMIZE TABLE 来重新 利用未使用的空间，并整理数据文件的碎片。 在多数的设置中，您根本不需要运行 OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新，您也不需要经常运行，每周一次或每月一次 即可，只对特定的表运行。 OPTIMIZE TABLE 只对 MyISAM, BDB 和 InnoDB 表起作用。 注意，在 OPTIMIZE TABLE 运行过程中，MySQL 会锁定表。 文章作者 明哥 文章地址 https://www.pvcreate.com/index.php/archives/107/ 创建时间 2017-06-18 关注订阅 微信订阅号 开源项目 https://gitee.com/lookingdreamer 工具市场 https://gitee.com/lookingdreamer/SPPPOTools
MYSQL数据库常用知识整理 什么是MYSQL MYSQL的特性 MYSQL存储引擎的分类以及数据文件的介绍 MYSQL赋权 MYSQL备份与恢复 MYSQL的基本操作:增删查改 MYSQL的基本故障判断与处理 MYSQL的调优 MYSQL主主、主从复制的实现 MYSQL大数据备份和恢复 数据文件的损坏与修复 什么是MYSQL MySQL[是一个开放源码的小型关联式数据库管理系统，开发者为瑞典MySQL AB公司。目前MySQL被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低，尤其是开放源码这一特点，许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。] MYSQL的特性 使用C和C++编写，并使用了多种编译器进行测试，保证源代码的可移植性。 支持AIX、BSDi、FreeBSD、HP-UX、Linux、Mac OS、Novell Netware、NetBSD、OpenBSD、OS/2 Wrap、Solaris、SunOS、Windows等多种操作系统。 为多种编程语言提供了API。这些编程语言包括C、C++、C#、Delphi、Eiffel、Java、Perl、PHP、Python、Ruby和Tcl等。 支持多线程，充分利用CPU资源，支持多用户。 优化的SQL查询算法，有效地提高查询速度。 既能够作为一个单独的应用程序应用在客户端服务器网络环境中，也能够作为一个库而嵌入到其他的软件中。 提供多语言支持，常见的编码如中文的GB 2312、BIG5，日文的Shift_JIS等都可以用作数据表名和数据列名。 提供TCP/IP、ODBC和JDBC等多种数据库连接途径。 提供用于管理、检查、优化数据库操作的管理工具。 可以处理拥有上千万条记录的大型数据库。 MYSQL存储引擎的分类以及数据文件的介绍 一、安装与部署、配置文件的介绍 ①安装简介 源码编译安装，请大家自己亲自动手编译安装。 (了解不同版本的区别尤其是5.5和5.6) ②配置文件说明 basedir = path 使用给定目录作为根目录(安装目录)。 character-sets-dir = path 给出存放着字符集的目录。 datadir = path 从给定目录读取数据库文件。 pid-file = filename 为mysqld程序指定一个存放进程ID的文件(仅适用于UNIX/Linux系统); Init-V脚本需要使用这个文件里的进程ID结束mysqld进程。 socket = filename 为MySQL客户程序与服务器之间的本地通信指定一个套接字文件(仅适用于UNIX/Linux系统; 默认设置一般是/var/lib/mysql/mysql.sock文件)。在Windows环境下，如果MySQL客户与服务器是通过命名管道进行通信 的，--sock选项给出的将是该命名管道的名字(默认设置是MySQL)。 lower_case_table_name = 1/0 新目录和数据表的名字是否只允许使用小写字母; 这个选项在Windows环境下的默认设置是1(只允许使用小写字母)。 mysqld程序：语言设置 character-sets-server = name 新数据库或数据表的默认字符集。为了与MySQL的早期版本保持兼容，这个字符集也可以用--default-character-set选项给出; 但这个选项已经显得有点过时了。 collation-server = name 新数据库或数据表的默认排序方式。 lanuage = name 用指定的语言显示出错信息。 mysqld程序：通信、网络、信息安全 enable-named-pipes 允许Windows 2000/XP环境下的客户和服务器使用命名管道(named pipe)进行通信。这个命名管道的默认名字是MySQL，但可以用--socket选项来改变。 local-infile [=0] 允许/禁止使用LOAD DATA LOCAL语句来处理本地文件。 myisam-recover [=opt1, opt2, ...] 在启动时自动修复所有受损的MyISAM数据表。这个选项的可取值有4种:DEFAULT、BACKUP、QUICK和FORCE; 它们与myisamchk程序的同名选项作用相同。 old-passwords 使用MySQL 3.23和4.0版本中的老算法来加密mysql数据库里的密码(默认使用MySQL 4.1版本开始引入的新加密算法)。 port = n 为MySQL程序指定一个TCP/IP通信端口(通常是3306端口)。 safe-user-create 只有在mysql.user数据库表上拥有INSERT权限的用户才能使用GRANT命令; 这是一种双保险机制(此用户还必须具备GRANT权限才能执行GRANT命令)。 shared-memory 允许使用内存(shared memory)进行通信(仅适用于Windows)。 shared-memory-base-name = name 给共享内存块起一个名字(默认的名字是MySQL)。 skip-grant-tables 不使用mysql数据库里的信息来进行访问控制(警告:这将允许用户任何用户去修改任何数据库)。 skip-host-cache 不使用高速缓存区来存放主机名和IP地址的对应关系。 skip-name-resovle 不把IP地址解析为主机名; 与访问控制(mysql.user数据表)有关的检查全部通过IP地址行进。 skip-networking 只允许通过一个套接字文件(Unix/Linux系统)或通过命名管道(Windows系统)进行本地连接，不允许ICP/IP连接; 这提高了安全性，但阻断了来自网络的外部连接和所有的Java客户程序(Java客户即使在本地连接里也使用TCP/IP)。 user = name mysqld程序在启动后将在给定UNIX/Linux账户下执行; mysqld必须从root账户启动才能在启动后切换到另一个账户下执行; mysqld_safe脚本将默认使用--user=mysql选项来启动mysqld程序。 mysqld程序：内存管理、优化、查询缓存区 bulk_insert_buffer_size = n 为一次插入多条新记录的INSERT命令分配的缓存区长度(默认设置是8M)。 key_buffer_size = n 用来存放索引区块的RMA值(默认设置是8M)。 join_buffer_size = n 在参加JOIN操作的数据列没有索引时为JOIN操作分配的缓存区长度(默认设置是128K)。 max_heap_table_size = n HEAP数据表的最大长度(默认设置是16M); 超过这个长度的HEAP数据表将被存入一个临时文件而不是驻留在内存里。 max_connections = n MySQL服务器同时处理的数据库连接的最大数量(默认设置是100)。 query_cache_limit = n 允许临时存放在查询缓存区里的查询结果的最大长度(默认设置是1M)。 query_cache_size = n 查询缓存区的最大长度(默认设置是0，不开辟查询缓存区)。 query_cache_type = 0/1/2 查询缓存区的工作模式:0, 禁用查询缓存区; 1，启用查询缓存区(默认设置); 2，”按需分配”模式，只响应SELECT SQL_CACHE命令。 read_buffer_size = n 为从数据表顺序读取数据的读操作保留的缓存区的长度(默认设置是128KB); 这个选项的设置值在必要时可以用SQL命令SET SESSION read_buffer_size = n命令加以改变。 read_rnd_buffer_size = n 类似于read_buffer_size选项，但针对的是按某种特定顺序(比如使用了ORDER BY子句的查询)输出的查询结果(默认设置是256K)。 sore_buffer = n 为排序操作分配的缓存区的长度(默认设置是2M); 如果这个缓存区太小，则必须创建一个临时文件来进行排序。 table_cache = n 同时打开的数据表的数量(默认设置是64)。 tmp_table_size = n 临时HEAP数据表的最大长度(默认设置是32M); 超过这个长度的临时数据表将被转换为MyISAM数据表并存入一个临时文件。 mysqld程序：日志 log [= file] 把所有的连接以及所有的SQL命令记入日志(通用查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname.log文件作为这种日志文件(hostname是服务器的主机名)。 log-slow-queries [= file] 把执行用时超过long_query_time变量值的查询命令记入日志(慢查询日志); 如果没有给出file参数，MySQL将在数据库目录里创建一个hostname-slow.log文件作为这种日志文件(hostname是服务器主机 名)。 long_query_time = n 慢查询的执行用时上限(默认设置是10s)。 long_queries_not_using_indexs 把慢查询以及执行时没有使用索引的查询命令全都记入日志(其余同--log-slow-queries选项)。 log-bin [= filename] 把对数据进行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二进制格式记入日志(二进制变更日志，binary update log)。这种日志的文件名是filename.n或默认的hostname.n，其中n是一个6位数字的整数(日志文件按顺序编号)。 log-bin-index = filename 二进制日志功能的索引文件名。在默认情况下，这个索引文件与二进制日志文件的名字相同，但后缀名是.index而不是.nnnnnn。 max_binlog_size = n 二进制日志文件的最大长度(默认设置是1GB)。在前一个二进制日志文件里的信息量超过这个最大长度之前，MySQL服务器会自动提供一个新的二进制日志文件接续上。 binlog-do-db = dbname 只把给定数 据库里的变化情况记入二进制日志文件，其他数据库里的变化情况不记载。如果需要记载多个数据库里的变化情况，就必须在配置文件使用多个本选项来设置，每个数据库一行。 binlog-ignore-db = dbname 不把给定数据库里的变化情况记入二进制日志文件。 sync_binlog = n 每经过n次日志写操作就把日志文件写入硬盘一次(对日志信息进行一次同步)。n=1是最安全的做法，但效率最低。默认设置是n=0，意思是由操作系统来负责二进制日志文件的同步工作。 log-update [= file] 记载出错情况的日志文件名(出错日志)。这种日志功能无法禁用。如果没有给出file参数，MySQL会使用hostname.err作为种日志文件的名字。 mysqld程序：镜像(主控镜像服务器) server-id = n 给服务器分配一个独一无二的ID编号; n的取值范围是1\~2的32次方启用二进制日志功能。 log-bin = name 启用二进制日志功能。这种日志的文件名是filename.n或默认的hostname.n，其中的n是一个6位数字的整数(日志文件顺序编号)。 binlog-do/ignore-db = dbname 只把给定数据库里的变化情况记入二进制日志文件/不把给定的数据库里的变化记入二进制日志文件。 mysqld程序：镜像(从属镜像服务器) +-----------------------------------+-----------------------------------+ server-id = n 给服务器分配一个唯一的ID编号 +-----------------------------------+-----------------------------------+ log-slave-updates 启用从属服务器上的日志功能，使这台计算机可以用来构成一个镜像链(A ->B->C)。 +-----------------------------------+-----------------------------------+ master-host = hostname 主控服务器的主机名或IP地址。如果从属服务器上存在mater.in fo文件(镜像关系定义文件)，它将忽略此选项。 +-----------------------------------+-----------------------------------+ master-user = replicusername 从属服务器用来连接主控服务器的用户名。如果从属服务器上存在mate r.info文件，它将忽略此选项。 +-----------------------------------+-----------------------------------+ master-password = passwd 从属服务器用来连接主控服务器的密码。如果从属服务器上存在mater .info文件，它将忽略此选项。 +-----------------------------------+-----------------------------------+ master-port = n 从属服务器用来连接主控服务器的TCP/IP端口(默认设置是3306 端口)。 +-----------------------------------+-----------------------------------+ master-connect-retry = n 如果与主控服务器的连接没有成功，则等待n秒(s)后再进行管理方式( 默认设置是60s)。如果从属服务器存在mater.info文件，它 将忽略此选项。 +-----------------------------------+-----------------------------------+ master-ssl-xxx = xxx 对主、从服务器之间的SSL通信进行配置。 +-----------------------------------+-----------------------------------+ read-only = 0/1 0: 允许从属服务器独立地执行SQL命令(默认设置); 1: 从属服务器只能执行来自主控服务器的SQL命令。 +-----------------------------------+-----------------------------------+ read-log-purge = 0/1 1: 把处理完的SQL命令立刻从中继日志文件里删除(默认设置); 0: 不把处理完的SQL命令立刻从中继日志文件里删除。 +-----------------------------------+-----------------------------------+ replicate-do-table = 与--replicate-do-table选项的含义和用法相同，但 dbname.tablename 数据库和数据库表名字里允许出现通配符”%” (例如: test%.%--对名字以”test”开头的所有数据库里的所以数据 库表进行镜像处理)。 +-----------------------------------+-----------------------------------+ | replicate-do-db = name | 只对这个数据库进行镜像处理。 | +-----------------------------------+-----------------------------------+ | replicate-ignore-table = | 不对这个数据表进行镜像处理。 | | dbname.tablename | | +-----------------------------------+-----------------------------------+ | replicate-wild-ignore-table = | 不对这些数据表进行镜像处理。 | | dbn.tablen | | +-----------------------------------+-----------------------------------+ | replicate-ignore-db = dbname | 不对这个数据库进行镜像处理。 | +-----------------------------------+-----------------------------------+ | replicate-rewrite-db = db1name | 把主控数据库上的db1name数据库镜像处理为从属服务器上的db2 | | > db2name | name数据库。 | +-----------------------------------+-----------------------------------+ | report-host = hostname | 从属服务器的主机名; | | | 这项信息只与SHOW SLAVE | | | HOSTS命令有关--主控服务器可以用这条命令生成一份从属服务器的 | | | 名单。 | +-----------------------------------+-----------------------------------+ | slave-compressed-protocol = 1 | 主、从服务器使用压缩格式进行通信--如果它们都支持这么做的话。 | +-----------------------------------+-----------------------------------+ | slave-skip-errors = n1, n2, | 即使发生出错代码为n1、n2等的错误，镜像处理工作也继续进行(即不 | | ...或all | 管发生什么错误，镜像处理工作也继续进行)。如果配置得当，从属服务器 | | | 不应该在执行 | | | SQL命令时发生错误(在主控服务器上执行出错的SQL命令不会被发送 | | | 到从属服务器上做镜像处理); | | | 如果不使用slave-skip-errors选项，从属服务器上的镜 | | | 像工作就可能因为发生错误而中断，中断后需要有人工参与才能继续进行。 | +-----------------------------------+-----------------------------------+ mysqld--InnoDB：基本设置、表空间文件 skip-innodb 不加载InnoDB数据表驱动程序--如果用不着InnoDB数据表，可以用这个选项节省一些内存。 innodb-file-per-table 为每一个新数据表创建一个表空间文件而不是把数据表都集中保存在中央表空间里(后者是默认设置)。该选项始见于MySQL 4.1。 innodb-open-file = n InnoDB数据表驱动程序最多可以同时打开的文件数(默认设置是300)。如果使用了innodb-file-per-table选项并且需要同时打开很多数据表的话，这个数字很可能需要加大。 innodb_data_home_dir = p InnoDB主目录，所有与InnoDB数据表有关的目录或文件路径都相对于这个路径。在默认的情况下，这个主目录就是MySQL的数据目录。 innodb_data_file_path = ts 用来容纳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。 innodb_autoextend_increment = n 带有autoextend属性的表空间文件每次加大多少兆字节(默认设置是8MB)。这个属性不涉及具体的数据表文件，那些文件的增大速度相对是比较小的。 innodb_lock_wait_timeout = n 如果某个事务在等待n秒(s)后还没有获得所需要的资源，就使用ROLLBACK命令放弃这个事务。这项设置对于发现和处理未能被InnoDB数据表驱动 程序识别出来的死锁条件有着重要的意义。这个选项的默认设置是50s。 innodb_fast_shutdown 0/1 是否以最快的速度关闭InnoDB，默认设置是1，意思是不把缓存在INSERT缓存区的数据写入数据表，那些数据将在MySQL服务器下次启动时再写入 (这么做没有什么风险，因为INSERT缓存区是表空间的一个组成部分，数据不会丢失)。把这个选项设置为0反面危险，因为在计算机关闭时，InnoDB 驱动程序很可能没有足够的时间完成它的数据同步工作，操作系统也许会在它完成数据同步工作之前强行结束InnoDB，而这会导致数据不完整。 mysqld程序：InnoDB--日志 innodb_log_group_home_dir = p 用来存放InnoDB日志文件的目录路径(如ib_logfile0、ib_logfile1等)。在默认的情况下，InnoDB驱动程序将使用 MySQL数据目录作为自己保存日志文件的位置。 innodb_log_files_in_group = n 使用多少个日志文件(默认设置是2)。InnoDB数据表驱动程序将以轮转方式依次填写这些文件; 当所有的日志文件都写满以后，之后的日志信息将写入第一个日志文件的最大长度(默认设置是5MB)。这个长度必须以MB(兆字节)或GB(千兆字节)为单 位进行设置。 innodb_flush_log_at_trx_commit = 0/1/2 这个选项决定着什么时候把日志信息写入日志文件以及什么时候把这些文件物理地写(术语称为”同步”)到硬盘上。设置值0的意思是每隔一秒写一次日志并进行 同步，这可以减少硬盘写操作次数，但可能造成数据丢失; 设置值1(设置设置)的意思是在每执行完一条COMMIT命令就写一次日志并进行同步，这可以防止数据丢失，但硬盘写操作可能会很频繁; 设置值2是一般折衷的办法，即每执行完一条COMMIT命令写一次日志，每隔一秒进行一次同步。 innodb_flush_method = x InnoDB日志文件的同步办法(仅适用于UNIX/Linux系统)。这个选项的可取值有两种: fdatasync，用fsync()函数进行同步; O_DSYNC，用O_SYNC()函数进行同步。 innodb_log_archive = 1 启用InnoDB驱动程序的archive(档案)日志功能，把日志信息写入ib_arch_log_n文件。启用这种日志功能在InnoDB与 MySQL一起使用时没有多大意义(启用MySQL服务器的二进制日志功能就足够用了)。 mysqld程序--InnoDB：缓存区的设置和优化 +-----------------------------------+-----------------------------------+ innodb_log_buffer_pool_size = 为InnoDB数据表及其索引而保留的RAM内存量(默认设置是8MB n )。这个参数对速度有着相当大的影响，如果计算机上只运行有 MySQL/InnoDB数据库服务器，就应该把全部内存的80%用于 这个用途。 +-----------------------------------+-----------------------------------+ | innodb_log_buffer_size = n | 事务日志文件写操作缓存区的最大长度(默认设置是1MB)。 | +-----------------------------------+-----------------------------------+ | innodb_additional_men_pool_si | 为用于内部管理的各种数据结构分配的缓存区最大长度(默认设置是1MB | | ze | )。 | | = n | | +-----------------------------------+-----------------------------------+ | innodb_file_io_threads = n | I/O操作(硬盘写操作)的最大线程个数(默认设置是4)。 | +-----------------------------------+-----------------------------------+ | innodb_thread_concurrency = n | InnoDB驱动程序能够同时使用的最大线程个数(默认设置是8)。 | +-----------------------------------+-----------------------------------+ mysqld程序：其它选项 bind-address = ipaddr MySQL服务器的IP地址。如果MySQL服务器所在的计算机有多个IP地址，这个选项将非常重要。 default-storage-engine = type 新数据表的默认数据表类型(默认设置是MyISAM)。这项设置还可以通过--default-table-type选项来设置。 default-timezone = name 为MySQL服务器设置一个地理时区(如果它与本地计算机的地理时区不一样)。 ft_min_word_len = n 全文索引的最小单词长度工。这个选项的默认设置是4，意思是在创建全文索引时不考虑那些由3个或更少的字符构建单词。 Max-allowed-packet = n 客户与服务器之间交换的数据包的最大长度，这个数字至少应该大于客户程序将要处理的最大BLOB块的长度。这个选项的默认设置是1MB。 Sql-mode = model1, mode2, ... MySQL将运行在哪一种SQL模式下。这个选项的作用是让MySQL与其他的数据库系统保持最大程度的兼容。这个选项的可取值包括ansi、db2、 oracle、no_zero_date、pipes_as_concat。 \ \ ③启动脚本 \ \ 二、MYSQL存储引擎的分类: MYISAM INNODB \ [myISAM：这个是默认类型，它是基于传统的ISAM类型，ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写，它是存储记录和文件的标准方法。与其他存储引擎比较，MyISAM具有检查和修复表格的大多数工具。 MyISAM表格可以被压缩，而且它们支持全文搜索。它们不是事务安全的，而且也不支持外键。如果事物回滚将造成不完全回滚，不具有原子性。如果执行大量的]SELECT，MyISAM是更好的选择。 MyIASM是IASM表的新版本，有如下扩展： 二进制层次的可移植性。 NULL列索引。 对变长行比ISAM表有更少的碎片。 支持大文件。 更好的索引压缩。 更好的键吗统计分布。 更好和更快的auto_increment处理。 [InnoDB：这种类型是事务安全的。它与BDB类型具有相同的特性，它们还支持外键。InnoDB表格速度很快，具有比BDB还丰富的特性， 因此如果需要一个事务安全的存储引擎，建议使用它。如果你的数据执行大量的]INSERT或UPDATE，出于性能方面的考虑，应该使用InnoDB表。对 于支持事物的InnoDB类型的表，影响速度的主要原因是AUTOCOMMIT默认设置是打开的，而且程序没有显式调用BEGIN 开始事务，导致每插入一条都自动Commit，严重影响了速度。可以在执行sql前调用begin，多条sql形成一个事物(即使autocommit打 开也可以)，将大大提高性能。 具体可以看看下表： +----------------------+----------------------+----------------------+ \ MyISAM InnoDB +----------------------+----------------------+----------------------+ 构成上区别 每个MyISAM在磁盘上存储成三个文件。 基于磁盘的资源是InnoDB表空间数据文 文件名为表名，扩展名为文件类型。 件和它的日志文件，InnoDB 表的大小只受限于操作系统文件的大小，一般 .frm 为 文件存储表定义；\ 2GB .MYD(MYData) 数据文件的扩展名；\ .MYI(MYIndex) 索引文件的扩展名。 +----------------------+----------------------+----------------------+ 事务处理方面 MyISAM类型的表强调的是性能，其执行 InnoDB提供事务支持事务，外 速度比InnoDB类型更快，但是不提供事 部键等高级数据库功能。 务支持。 +----------------------+----------------------+----------------------+ 锁 表级锁 行级锁 InnoDB表的行锁也不是绝对的，如果在 执行一个SQL语句时MySQL不能确定要 扫描的范围，InnoDB表同样会锁全表， 例如update table set num=1 where name like “%aaa%” +----------------------+----------------------+----------------------+ **select、insert、upda 如果执行大量的 1.如果你的数据执行大量的INSERT或 te、delete操作** SELECT，MyISAM UPDATE，出于性能方面的考虑，应该使 是更好的选择。 用InnoDB表。 2.DELETE FROM table时，InnoDB不会重新建立表 ，而是一行一行的删除。 3.LOAD TABLE FROM MASTER操作对InnoDB是不起作用 的，解决方法是首先把InnoDB表改成M yISAM表，导入数据后再改成InnoD B表，但是对于使用的额外的InnoDB特 性（例如外键）的表不适用。 +----------------------+----------------------+----------------------+ | 对于AUTO_INCREMENT类 | 必须包含只有该字段的索引 | 可以和其他字段一起建立联合索引 | | 型的字段 | | | +----------------------+----------------------+----------------------+ | \ | \ | InnoDB不支持FULLTEXT类型的 | | | | 索引。 | +----------------------+----------------------+----------------------+ | \ | MyISAM类型的二进制数据文件可以在不 | \ | | | 同操作系统中迁移 | | +----------------------+----------------------+----------------------+ 以下是一些细节和具体实现的差别： InnoDB不支持FULLTEXT类型的索引。 InnoDB 中不保存表的具体行数，也就是说，执行select count(*) from table时，InnoDB要扫描一遍整个表来计算有多少行，但是MyISAM只要简单的读出保存好的行数即可。注意的是，当count(*)语句包含 where条件时，两种表的操作是一样的。 对于AUTO_INCREMENT类型的字段，InnoDB中必须包含只有该字段的索引，但是在MyISAM表中，可以和其他字段一起建立联合索引。 DELETE FROM table时，InnoDB不会重新建立表，而是一行一行的删除。 LOAD TABLE FROM MASTER操作对InnoDB是不起作用的，解决方法是首先把InnoDB表改成MyISAM表，导入数据后再改成InnoDB表，但是对于使用的额外的InnoDB特性（例如外键）的表不适用。 综上所述，任何一种表都不是万能的，只有恰当的针对业务类型来选择合适的表类型，才能最大的发挥MySQL的性能优势。 二、MYSQL数据文件的介绍 一、MySQL数据库文件介绍 MySQL的每个数据库都对应存放在一个与数据库同名的文件夹中，MySQL数据库文件包括MySQL所建数据库文件和MySQL所用存储引擎创建的数据库文件。 1、MySQL创建并管理的数据库文件： .frm文件：存储数据表的框架结构，文件名与表名相同，每个表对应一个同名frm文件，与操作系统和存储引擎无关，即不管MySQL运行在何种操作系统上，使用何种存储引擎，都有这个文件。 除了必有的.frm文件，根据MySQL所使用的存储引擎的不同（MySQL常用的两个存储引擎是MyISAM和InnoDB），存储引擎会创建各自不同的数据库文件。 2、MyISAM数据库表文件： .MYD文件：即MY Data，表数据文件 .MYI文件：即MY Index，索引文件 .log文件：日志文件 3、InnoDB采用表空间（tablespace）来管理数据，存储表数据和索引， InnoDB数据库文件（即InnoDB文件集，ib-file set）： ibdata1、ibdata2等：系统表空间文件，存储InnoDB系统信息和用户数据库表数据和索引，所有表共用 .ibd文件：单表表空间文件，每个表使用一个表空间文件（file per table），存放用户数据库表数据和索引 日志文件： ib_logfile1、ib_logfile2 二、MySQL数据库存放位置： 1、MySQL如果使用MyISAM存储引擎，数据库文件类型就包括.frm、.MYD、.MYI，默认存放位置是C:\Documentsand Settings\All Users\Application Data\MySQL\MySQL Server 5.1\data 2、MySQL如果使用InnoDB存储引擎，数据库文件类型就包括.frm、ibdata1、.ibd，存放位置有两个， .frm文件默认存放位置是C:\Documents and Settings\All Users\ApplicationData\MySQL\MySQL Server 5.1\data，ibdata1、.ibd文件默认存放位置是MySQL安装目录下的data文件夹 \ \ 三、MYSQL赋权 \ #给用户cacti赋予所有库的所有权限\ GRANT ALL PRIVILEGES ON *.* TO \'cacti\'@\'%\' IDENTIFIED BY \'cacti\' WITH GRANT OPTION;\ #重新载入赋权表\ FLUSH PRIVILEGES;\ #收回权限(不包含赋权权限)\ REVOKE ALL PRIVILEGES ON *.* FROM cacti;\ REVOKE ALL PRIVILEGES ON cacti.* FROM cacti;\ #收回赋权权限\ REVOKE GRANT OPTION ON *.* FROM cacti;\ #重新载入赋权表\ FLUSH PRIVILEGES; #查看赋权权限 show grants for \'cacti\'@\'%\' \ 四、MYSQL备份与恢复 \ \ [一：实验环境介绍：]\ [系统介绍：CentOS6.4_X64] [数据库版本：mysql-5.5.33] [\ ] [二：基于Mysqldump命令实现备份恢复] [2.1] [[ Mysqldump] [ Mysqldump] [2.2] [ Mysqldump] [2.3] [（1）Mysqldump全备] [ 由于Mysql数据库默认的为MyISAM存储引擎所以只有使用温备（备份同时仅支持读请求）进行，所以我们要为所有数据库添加读锁] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | #mysqldump -uroot -pmypass - | | | -lock-all-tables --master-data=2 | | | --events --routines--all-database | | | s > /zhao/database_`date +%F`.sql | | | | +-----------------------------------+-----------------------------------+ [ 解析：--lock-all-tables表示为所有表施加读锁；--master-data=2表示在备份文件中记录当前二进制日志的位置；--events表示备份数据的同时备份时间调度器代码；--routines表示备份数据的同时备份存储过程和存储函数；--all-databases表示备份所有库。] +-----------------------------------+-----------------------------------+ 1 [root@stu18 zhao] `# less database_2013-08-13.sql 2 ` 3 -- #表示注释项 4 `-- Position to start replication 5 or point-` in 6 - time recovery from 7 -- 8 `-- CHANGE MASTER TO MASTER_LOG_F 9 ILE=` 'mysql-bin.000001' , MASTER_LOG_POS=14203; `#这里表示当前处于mysql-bin.000001这个二进制 日志中，事件为14203这是通过--master-data=2产生 的` -- ` -- Current Database:hellodb` `` -- `` CREATE DATABASE /*!32312 IF NO T EXISTS/ hellodb /!40100 DEF AULT CHARACTER SET utf8 */; `` +-----------------------------------+-----------------------------------+ [（2）二进制全备] [ 方法一： 导出二进制日志文件内容] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | ` # mysqlbinlog mysql-bin.0000 | | | 01 >/zhao/binlog_date +%F.sql | | | ` | +-----------------------------------+-----------------------------------+ [ 方法二：滚动日志复制文件]\ +-----------------------------------+-----------------------------------+ 1 `mysql> flush logs; ` 2 #滚动日志 [root@stu18 data] `# cp mysql-bin.000001 /zhao/my sql-bin.000001 #复制导出二进制文件` +-----------------------------------+-----------------------------------+ [（3）二进制增备] [ 首先添加数据信息] +-----------------------------------+-----------------------------------+ 1 mysql> use hellodb; 2 `mysql> INSERT INTO students(Name ,Age,Gender,ClassID,TeacherID) va lues (` 'Yang kang' ,22, 'M' ,3,3); +-----------------------------------+-----------------------------------+ [ 然后二进制增备] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | # mysqlbinlog --start-positi | | | on=14203 --stop-position=14527 my | | | sql-bin.000001 > /zhao/binlog_`da | | | te +%F_%H`.sql | +-----------------------------------+-----------------------------------+ [ 解析：--start-position=14203是上次全备之后的二进制事件位置；--stop-position=14527最近一天的二进制事件位置。] [2.4、] +-----------------------------------+-----------------------------------+ 1 `mysql> DROP DATABASE hellodb; ` 2 #删除数据库 3 `############下面这些过程要在离线状态下执行##### #######` 4 `mysql> SET sql_log_bin=0; 5 ` #先关闭二进制日志 6 `mysql> flush logs; 7 ` #滚动日志 8 [root@stu18 ~] `# mysql -uroot -pmypass < /zha o/database_2013-08-13.sql #导入数据库 备份文件` [root@stu18 ~] `# mysql -uroot -pmypass < /zha o/binlog_2013-08-13_19.sql #导入增量备 份文件` [root@stu18 ~] `# mysql -uroot –pmypass #登录 查看，恢复完成` `mysql> SET sql_log_bin=1; ` #开启二进制日志 +-----------------------------------+-----------------------------------+ [ 这种备份方式恢复简单，但是恢复还原之后索引会出现错误需要重建，而且备份结果会占据很大的空间，请酌情使用。] [三、基于LVM快照实现备份恢复] [3.1] [（1）LVM这种备份方式要求Mysql的数据保存在逻辑卷上] [（2）需要给Mysql服务器施加读锁（mysql>FLUSH TABLES WITH READLOCK;），这里不可直接退出服务器] [（3）另起终端为数据所在的卷创建快照（lvcreate），保证事务日志和数据文件必须在同一卷上（分别创建可能会导致数据文件和事务日志不一致，从而可能导致无法正常恢复）] [3.2] [ LVM] [3.3] [[ （1）创建逻辑卷及挂载逻辑卷，此过程在此就不做演示了可参考博文] [[ https://pangge.blog.51cto.com/6013757/1256568] [ （2）] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # cd /usr/local/mysql/ | | 2 | | | | [root@stu18 mysql] | | | | | | # scripts/mysql_install_db --u | | | ser=mysql --datadir=/mydata/data | +-----------------------------------+-----------------------------------+ [ （3）编辑查看配置文件，重启服务] +-----------------------------------+-----------------------------------+ 1 [root@stu18 mysql] # vim /etc/my.cnf 2 datadir = 3 /mydata/data 4 #查看此项是否定义数据目录位置 sync_binlog=1 `#添加此项，每个事务提交时候，把事务日志从缓存区写到日志文件 中，并且刷新日志文件的数据到磁盘上；` [root@stu18 mysql] # service mysqld start +-----------------------------------+-----------------------------------+ [3.4、过程展示] [ （1）确保事务日志和数据文件必须在同一卷上] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # ls /mydata/data/ 2 `hellodb myclass m 3 ysql-bin.000003 stu18.magedu.c om.err` 4 `ibdata1 mysql m 5 ysql-bin.000004 stu18.magedu.c om.pid` `ib_logfile0 mysql-bin.000001 m ysql-bin.index student` `ib_logfile1 mysql-bin.000002 p erformance_schema ` test +-----------------------------------+-----------------------------------+ [ 解析：其中ib_logfile0与ib_logfile1是日志文件]\ [ （2）施加全局锁并滚动日志] +-----------------------------------+-----------------------------------+ | 1 | mysql> FLUSH TABLES WITH READ LO | | | CK; | | 2 | | | | mysql> FLUSH LOGS; | +-----------------------------------+-----------------------------------+ [ （3）查看并保存当前正在使用的二进制日志及当前执行二进制日志位置（非常重要）] +-----------------------------------+-----------------------------------+ 1 mysql> SHOW MASTER STATUS; 2 `+------------------+----------+- -------------+------------------+ 3 ` 4 ` File Position Binlog_Do_DB Binlog_Ignore_DB 5 ` 6 `+------------------+----------+- -------------+------------------+ 7 ` ` mysql-bin.000004 187 ` `+------------------+----------+- -------------+------------------+ ` [root@stu18 zhao] `# mysql -uroot -pmypass -e 'SH OW MASTER STATUS;' >/zhao/lvmback -2013-08-14/binlog.txt` +-----------------------------------+-----------------------------------+ [ （4）创建快照卷] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 zhao] | | | # lvcreate -L 100M -s -p r -n | | | mydata-lvm /dev/vg1/mydata | +-----------------------------------+-----------------------------------+ [ （5）立即切换终端释放锁] +-----------------------------------+-----------------------------------+ | 1 | mysql> UNLOCK TABLES; | +-----------------------------------+-----------------------------------+ [ （6）备份数据] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | # cp -a * /zhao/lvmback-2013-0 | | | 8-14/ | +-----------------------------------+-----------------------------------+ [ （7）二进制实现增量备份] +-----------------------------------+-----------------------------------+ 1 mysql> use hellodb; 2 #指定默认数据库 3 Database changed 4 mysql> CREATE TABLE testtb ( id 5 int,name CHAR(10)); #创建表 6 `Query OK, 0 rows affected (0.35 7 sec)` `mysql> INSERT INTO testtb VALUES (1,` 'tom' ); #添加数据 `Query OK, 1 row affected (0.09 s ec)` [root@stu18 data] `# mysqlbinlog --start-position =187 mysql-bin.000004 > /zhao/lvm logbin_2013-08-14/binlog.sql #日志实现增量备份` +-----------------------------------+-----------------------------------+ [ （8）模拟数据库崩溃] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # service mysqld stop 2 [root@stu18 ~] 3 # cd /mydata/data/ [root@stu18 data] # rm -rf * +-----------------------------------+-----------------------------------+ [ （9）恢复数据] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] `# cp /zhao/lvmback-2013-08-14/ 2 * /mydata/data/ -a #完全备份 恢复` 3 [root@stu18 ~] 4 `# cd /mydata/data/ #查看恢复数据内容` 5 [root@stu18 data] 6 `# chown -R mysql.mysql * #更 改属主属组` 7 [root@stu18 data] 8 `# service mysqld start #启 动服务` 9 [root@stu18 data] 10 `# mysql -uroot –pmypass #登录 测试` 11 mysql> SHOW DATABASES; 12 #查看数据完整性，无测试表testtd使用二进制恢复 13 14 mysql> SET sql_log_bin=0 #关闭二进制日志 15 mysql> 16 source `/zhao/lvmlogbin_2013-08-14/bin 17 log` .sql; 18 #二进制恢复 19 mysql> SHOW TABLES; #查看恢复结果 20 +-------------------+ 21 | Tables_in_hellodb | 22 +-------------------+ | classes | | coc | | courses | | scores | | students | | teachers | | testtb | | toc | +-------------------+ mysql> SET sql_log_bin=1; #开启二进制日志 +-----------------------------------+-----------------------------------+ [\ ] [此工具是接近于热备的方式实现的，并且用此方法来备份恢复数据速度是非常快的。] [四:基于xtrabackup来实现备份恢复] [4] [ 完全以热备的形式进行，能够实现快速可靠地完全备份和部分备份，支持增量备份，支持时间点还原，备份过程中不会打扰到事务操作，能够实现网络传输和压缩功能从而有效的节约磁盘空间，备份完成后可自动验证数据是否可用，恢复速度较快等等。更多优势特性请参考https://www.percona.com/software/percona-xtrabackup] [注意：以上这些优势特性只能在InnoDB引擎上完美实现，而在MyISAM存储引擎上依然最多只能使用温备的形式进行并且还不支持增量备份。] [另外Xtrabackup更多的高级功能还依赖于Mysql数据库对于InnoDB实现了单独的表空间，否则也就没有办法实现单表导入导出查看方式如下：] +-----------------------------------+-----------------------------------+ 1 `mysql> SHOW GLOBAL VARIABLES LIK E ` 2 'innodb_file%' ; 3 `+--------------------------+---- 4 ------+` 5 ` Variable_name Val ue ` 6 `+--------------------------+---- 7 ------+` 8 ` innodb_file_format Ant elope ` 9 ` innodb_file_format_check ON ` ` innodb_file_format_max Ant elope ` ` innodb_file_per_table ON ` `+--------------------------+---- ------+` +-----------------------------------+-----------------------------------+ [ 其中的innodb_file_per_table为ON则表示实现了单表单空间。若为OFF则需要使用mysqldump全备然后更改配置文件删除原来的数据文件并重新初始化服务器最后将数据重新导入。所以建议以后在安装Mysql服务器时将其选项默认设置成1即可（innodb_file_per_table = 1）。单表单空间的数据显示形式为：] +-----------------------------------+-----------------------------------+ 1 [root@stu18 hellodb] # ls 2 `classes.frm coc.MYD course 3 s.MYI scores.MYI teachers.frm testtb.ibd` 4 `classes.MYD coc.MYI db.opt 5 students.frm teachers.MYD toc.frm` `classes.MYI courses.frm scores .frm students.MYD teachers.MYI toc.MYD` `coc.frm courses.MYD scores .MYD students.MYI testtb.frm toc.MYI` +-----------------------------------+-----------------------------------+ [4.2、安装Xtrabackup] [ 下载percona-xtrabackup最新的版本为2.1.4（percona-xtrabackup-2.1.4-656.rhel6.x86_64.rpm）] [ 安装：] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~]# rpm -ivh percona | | | -xtrabackup- | | | 2.1 | | | . 4 | | | - 656 | | | .rhel6.x86_64.rpm | +-----------------------------------+-----------------------------------+ 若有错误无法安装请安装perl-DBD-mysql依赖包 +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~]# yum -y install p | | | erl-DBD-mysql | +-----------------------------------+-----------------------------------+ [ 注意：不同的环境依赖的关系包可能有多个，请依照提示进行配置] [4.3] [ 使用innobakupex备份时，其会调用xtrabackup备份所有的InnoDB表，复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件，同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。完全备份] +-----------------------------------+-----------------------------------+ | 1 | # innobackupex --user=DBUSER--pa | | | ssword=DBUSERPASS /path/to/BACKUP | | | -DIR/ | +-----------------------------------+-----------------------------------+ [ 实现过程及说明：] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] `# mkdir /innobackup 2 #创建备份文件目录` 3 [root@stu18 ~] `# innobackupex --user=root --p 4 assword=mypass /innobackup/ #完 全备份` 5 `################如果执行正确其后输出的几行信息通 6 常如下###############` 7 `xtrabackup: Transaction log of l sn (1604655) to (1604655) was cop 8 ied. ` 9 #二进制日志的位置（lsn） `130814 07:04:55 innobackupex: A ll tables unlocked` innobackupex: Backup created in directory `'/innobackup/2013-08-14_07-04- 49'` #备份文件保存的位置 `innobackupex: MySQL binlog posit ion: filename ` 'mysql-bin.000003' , position 538898 `130814 07:04:55 innobackupex: C onnection to database server clos ed` `130814 07:04:55 innobackupex: c ompleted OK! 备份完成` +-----------------------------------+-----------------------------------+ [ 切换至备份文件目录查看备份的数据信息及创建生成的文件：] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] `# cd /innobackup/2013-08-14_07 2 -04-49/` 3 `[root@stu18 2013-08-14_07-04-49] ` 4 # ls 5 `backup-my.cnf myclass student xtrabackup_ binlog_info` `hellodb mysql ` test xtrabackup_checkpoints `ibdata1 performance_schem a xtrabackupbinary xtrabackup logfile` +-----------------------------------+-----------------------------------+ [ 针对文件解析：] [ (1)xtrabackup_checkpoints ------ 备份类型（如完全或增量）、备份状态（如是否已经为prepared状态）和LSN(日志序列号)范围信息；] [ 每个InnoDB页(通常为16k大小)都会包含一个日志序列号，即LSN。LSN是整个数据库系统的系统版本号，每个页面相关的LSN能够表明此页面最近是如何发生改变的。] [ (2)xtrabackup_binlog_info ][------ mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。] [ (3)xtrabackup_binary ][------ 备份中用到的xtrabackup的可执行文件；] [ (4)backup-my.cnf ][------ 备份时用到的配置选项信息，也就是配置文件中关于mysqld的相关文件配置；] [ (5) xtrabackup_logfile ][------ 非文本文件是xtrabackup本身的日志文件；] [4.4、准备一个完全备份] [ 一般情况下，在备份完成后，数据尚且不能用于恢复操作，因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此，此时数据文件仍处于不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件从而使得数据文件处于一致性状态。] [ innobakupex] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] `# innobackupex -apply-log /inn 2 obackup/2013-08-14_07-04-49/` 3 `#############如果执行正确，其最后输出的几行信息通常 如下################` 4 xtrabackup: starting 5 shutdown with innodb_fast_shutdown = 1 6 `130814 7:39:33 InnoDB: Startin g ` shutdown ... `130814 7:39:37 InnoDB: Shutdow n completed; log sequence number 1606156` `130814 07:39:37 innobackupex: c ompleted OK!` +-----------------------------------+-----------------------------------+ [4.5、模拟数据库崩溃实现完全恢复] [ （1）模拟崩溃] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # service mysqld stop 2 [root@stu18 ~] 3 # cd /mydata/data/ [root@stu18 data] # rm -rf * +-----------------------------------+-----------------------------------+ [（2）从完全备份中恢复数据]\ [ innobackupex] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] `# innobackupex --copy-back /in 2 nobackup/2013-08-14_07-04-49/` 3 `#############如果执行正确，其最后输出的几行信息通常 如下################` 4 `innobackupex: Starting to copy I 5 nnoDB log files` 6 innobackupex: in 7 `'/innobackup/2013-08-14_07-04- 49'` 8 `innobackupex: back to original I 9 nnoDB log directory ` '/mydata/data' innobackupex: Copying `'/innobackup/2013-08-14_07-04- 49/ib_logfile0'` to '/mydata/data' innobackupex: Copying `'/innobackup/2013-08-14_07-04- 49/ib_logfile1'` to '/mydata/data' `innobackupex: Finished copying b ack files.` `130814 07:58:22 innobackupex: c ompleted OK!` +-----------------------------------+-----------------------------------+ [（3）当数据恢复至数据目录以后，还需要确保所有数据文件的属主和属组均为正确的用户，如mysql，否则，在启动mysqld之前还需要事先修改数据文件的属主和属组。] +-----------------------------------+-----------------------------------+ | 1 | # chown -R mysql:mysql /mydata/ | | | data/ | +-----------------------------------+-----------------------------------+ [（4）启动服务器登陆查看恢复完成。]\ +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | # service mysqld start | +-----------------------------------+-----------------------------------+ [ 注意：每一次恢复完成之后一定要重新做一次完全备份工作！！] [4.6、使用innobackupex进行增量备份] [ 说明：每个InnoDB的页面都会包含一个LSN信息，每当相关的数据发生改变，相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础，即innobackupex通过备份上次完全备份之后发生改变的页面来实现。] [[第一次改动数据实现增量备份] [ 实现增量备份可以使用下面的命令进行：] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | # innobackupex --user=root --p | | | assword=mypass --incremental /inn | | | obackup --incremental-basedir=/in | | | nobackup/2013-08-14_08-14-12/ | +-----------------------------------+-----------------------------------+ [ 其中，/innobackup指的是完全备份所在的目录，此命令执行结束后，innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。--incremental-basedir是指向上一次完全备份所在的目录。] [[第二次改动数据进行增量备份] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # innobackupex --user=root --p | | | assword=mypass --incremental /inn | | | obackup --incremental-basedir=/in | | | nobackup/2013-08-14_08-29-05/ | +-----------------------------------+-----------------------------------+ [ 第二次增量备份的执行命令和第一次大致相同，只有其--incremental-basedir应该指向上一次的增量备份所在的目录。] [第三次改动数据还未进行增量备份] +-----------------------------------+-----------------------------------+ | 1 | mysql> delete from coc where | | | id | | | =14; | +-----------------------------------+-----------------------------------+ [4.7、使用innobackupex基于完全+增量+二进制日志恢复数据] [ （1）由于笔者这里将二进制日志和数据文件写在了同一个文件目录下所以在模拟数据库崩溃前必须先复制出二进制日志文件，所以[建议看客们将数据目录和二进制目录分开存放] [[ 前提是在刚刚建立服务器尚未启动服务器之前做如下操作] +-----------------------------------+-----------------------------------+ 1 mkdir /mybinlog 2 #建立一目录用于存放二进制日志 3 chown 4 mysql:mysql /mybinlog #更改权限 vim /etc/my .cnf #修改配置文件 log-bin= /mybinlog/mysql-bin #二进制日志目录及文件名前缀，添加之 +-----------------------------------+-----------------------------------+ [[ 好了言归正传[复制二进制日志文件]\ +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 data] | | | # cp mysql-bin.000001/innoback | | | up/ | +-----------------------------------+-----------------------------------+ [ （2）模拟服务器崩溃] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # service mysqld stop 2 [root@stu18 ~] 3 # cd /mydata/data/ [root@stu18 data] # rm -rf * +-----------------------------------+-----------------------------------+ [ （3）准备备份]\ [ 首先注意“准备”增量备份与整理完全备份有着一些不同，尤其要注意的是：] [ 1)] [ 2)] [完全备份“准备”] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # innobackupex --apply-log --r | | | edo-only/innobackup/2013-08-14_08 | | | -14-12/ | +-----------------------------------+-----------------------------------+ [第一次增量备份“准备”也就是说将第一次增量备份合并到了完全备份中]\ +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # innobackupex --apply-log--re | | | do-only /innobackup/2013-08-14_08 | | | -14-12/--incremental-dir=/innobac | | | kup/2013-08-14_08-29-05/ | +-----------------------------------+-----------------------------------+ [第二次增量备份“准备”也就是说将第二次增量备份也合并到了完全备份中]\ +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # innobackupex --apply-log--re | | | do-only /innobackup/2013-08-14_08 | | | -14-12/ --incremental-dir=/innoba | | | ckup/2013-08-14_09-08-39/ | +-----------------------------------+-----------------------------------+ [[ 其中 --redo-only是只将已提交的事务同步到数据文件中，未提交的事务日志不在进行回滚了] [ （4）恢复数据（基于innobackupex基于完全+增量）] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # innobackupex --copy-back/inn | | | obackup/2013-08-14_08-14-12/ | +-----------------------------------+-----------------------------------+ [ （5）更改属组属主] +-----------------------------------+-----------------------------------+ | 1 | [root@stu18 ~] | | | # cd /mydata/data/ | | 2 | | | | [root@stu18 data] | | | # chown -R mysql:mysql * | +-----------------------------------+-----------------------------------+ [ （6）启动查看] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # mysql -uroot -pmypas 2 mysql> 3 select * from coc; 4 +----+---------+----------+ 5 ` ID ClassID CourseID ` 6 +----+---------+----------+ 7 ` 1 1 2 ` 8 ` 2 1 5 ` 9 ` 3 2 2 ` 10 ` 4 2 6 ` 11 ` 5 3 1 ` 12 ` 6 3 7 ` 13 ` 7 4 5 ` 14 ` 8 4 2 ` 15 ` 9 5 1 ` 16 ` 10 5 9 ` 17 ` 11 6 3 ` 18 ` 12 6 4 ` 19 ` 13 7 4 ` 20 ` 14 7 3 ` 21 +----+---------+----------+ 14 rows in set (0.00 sec) +-----------------------------------+-----------------------------------+ [ 结果显示数据正确完整，但是第三次的改动信息未生效。]\ [ （7）基于二进制日志实现数据恢复] [ 查看最后一次增量备份二进制日志所在的位置：] +-----------------------------------+-----------------------------------+ 1 [root@stu18 data] `# cd /innobackup/2013-08-14_09 2 -08-39/` 3 `[root@stu18 2013-08-14_09-08-39] ` # cat xtrabackup_binlog_info mysql-bin.000001 780 +-----------------------------------+-----------------------------------+ [ 查看二进制日志文件将未备份数据的二进制日志导出] +-----------------------------------+-----------------------------------+ 1 [root@stu18 innobackup] 2 `# mysqlbinlog mysql-bin.000001 ` 3 # at 780 4 `#130814 9:20:19 server id 1 en 5 d_log_pos 851 Query thread_id =7 exec_time=0 error_code=0` 6 SET TIMESTAMP=1376443219/*!*/; 7 BEGIN 8 /*!*/; 9 # at 851 10 `#130814 9:20:19 server id 1 en 11 d_log_pos 944 Query thread_id =7 exec_time=0 error_code=0` 12 SET TIMESTAMP=1376443219/*!*/; 13 delete from coc where 14 id =14 15 /*!*/; 16 # at 944 17 `#130814 9:20:19 server id 1 en 18 d_log_pos 1016 Query thread_id =7 exec_time=0 error_code=0` 19 SET TIMESTAMP=1376443219/*!*/; 20 COMMIT 21 /*!*/; 22 DELIMITER ; # End of log file `ROLLBACK /* added by mysqlbinlog */;` `/*!50003 SET COMPLETION_TYPE=@OL D_COMPLETION_TYPE*/;` `/*!50530 SET @@SESSION.PSEUDO_SL AVE_MODE=0*/;` [root@stu18 innobackup] `# mysqlbinlog --start-position =780 mysql-bin.000001 > ./all.sql #导出数据` +-----------------------------------+-----------------------------------+ [ 恢复数据] +-----------------------------------+-----------------------------------+ 1 [root@stu18 ~] # mysql -uroot –pmypass 2 `mysql> SET SQL_LOG_BIN=0; 3 ` #关闭二进制日志 4 mysql> 5 source /innobackup/all 6 .sql #导入数据 7 `mysql> SET SQL_LOG_BIN=1; 8 ` #开启二进制日志 9 mysql> 10 select * from coc; 11 #查看数据，恢复完成 12 +----+---------+----------+ 13 | ID | ClassID | CourseID | 14 +----+---------+----------+ 15 | 1 | 1 | 2 | 16 | 2 | 1 | 5 | 17 | 3 | 2 | 2 | 18 | 4 | 2 | 6 | 19 | 5 | 3 | 1 | 20 | 6 | 3 | 7 | 21 | 7 | 4 | 5 | 22 | 8 | 4 | 2 | 23 | 9 | 5 | 1 | | 10 | 5 | 9 | | 11 | 6 | 3 | | 12 | 6 | 4 | | 13 | 7 | 4 | +----+---------+----------+ 13 rows in set (0.00 sec) +-----------------------------------+-----------------------------------+ [ 这种备份恢复方式完全以热备的形式实现完全备份和增量备份和二进制日志还原数据，并且恢复速度也很快，是最佳的备份恢复方式！！] [\ ] [ 总结：以上三种备份恢复都是可以基于二进制日志文件进行的，因而体现出了二进制日志的重要性，从而映射出了日志的重要性；所以学习查看使用日志文件是学习Mysql的重中之重！] \ 五、MYSQL的基本操作:增删查改 [1、创建数据库： create database <数据库名>；]\ [如：create database student;]\ [2、连接到一个已经存在的数据库： use <数据库名>；]\ [如：use student;]\ [3、删除数据库：drop database <数据库名>；]\ [如： drop database student;]\ [4、创建表：create table <表名>(<列名><列的数据类型>[<列的约束>])]\ [如：create table stuInfo(stuId int primary key,stuName varchar(20) not null)]\ [5、删除表： drop table <表名>]\ [如: drop table stuInfo;]\ [6、修改表：alter table ]\ [给表添加新列： alter table <表名> add <列名><列的数据类型>；]\ [添加多列，中间用逗号隔开]\ [如：alter table stuInfo add stuGender varchar(10)]\ [修改某列的数据类型：alter table <表名> modify <列名><新数据类型>]\ [如：alter table stuInfo modify stuGender int]\ [修改列名：alter table <表名> change <老列名><新列名><数据类型>]\ [如：alter table stuInfo change stuName stuAddress varchar(30)]\ [删除列：alter table <表名> drop <列名>]\ [如： alter table stuInfo drop stuGender]\ [7、将创建的表的语句反向导出： show create table <表名>]\ [8、查询表的所有内容：select * from <表名>]\ [查询表的部分内容： select <列名列表> from <表名>]\ [9、查询表结构：show columns from <表名>]\ [10、插入单行数据：insert into <表名>(<列名列表>) values(<值列表>)]\ [11、插入多行数据：作用相当于将数据从一个表复制到另一个表]\ [insert into <表名> (列名列表) select <select语句>]\ [如将stuInfo表中的所有的学生姓名复制到students表中的stuName列中：insert into students(stuName) select stuName from stuInfo]\ [12、删除数据：delete from <表名> where<过滤条件>]\ [如删除stuID为4的人的数据：delete from stuInfo where stuId=4] \ \ 六、MYSQL的基本故障判断与处理 以下的文章主要介绍的是MySQL常见问题集锦，我们一共分成七大块对其进行说明，我们大家都知道MySQL数据库在是实际应用中的比例远少于Oracle，之所是这样的，肯定有它的不足之处 。 MySQL常见问题集锦之一： MySQL(和PHP搭配之最佳组合)总是崩溃 首先你应该试着找出问题MySQL(和PHP搭配之最佳组合)d守护进程是否死掉或你的问题是否与你的客户有关 。你可以用MySQL(和PHP搭配之最佳组合)admin version检查你的MySQL(和PHP搭配之最佳组合)d服务器正常执行了多长时间，如果MySQL(和PHP搭配之最佳组合)d死了，你可以在文件“MySQL(和PHP搭配之最佳组合)-data-directory/hostname.err”中找到其原因 。 使用MySQL(和PHP搭配之最佳组合)时的一些常见错误 MySQL(和PHP搭配之最佳组合) server has gone away 常见的原因是服务器超时了并且关闭了连接 。缺省地，如果没有事情发生，服务器在 8个小时后关闭连接 。你可在启动MySQL(和PHP搭配之最佳组合)d时通过设置wait_timeout变量改变时间限制 。 如果MySQL(和PHP搭配之最佳组合)d得到一个太大或不正常的包，它认为客户出错了并关闭连接 。 Cant connect to [local] MySQL(和PHP搭配之最佳组合) server 通常意味着没有一个MySQL(和PHP搭配之最佳组合)服务器运行在系统上或当试图连接MySQL(和PHP搭配之最佳组合)d服务器时，你正在使用一个错误的套接字文件或TCP/IP端口 。 检查(使用ps)服务器上是否有一个名为MySQL(和PHP搭配之最佳组合)d的进程启动 如果一个MySQL(和PHP搭配之最佳组合)d进程正在运行，可以通过尝试这些不同的连接来检查服务器 shell> MySQL(和PHP搭配之最佳组合)admin version shell> MySQL(和PHP搭配之最佳组合)admin variables shell> MySQL(和PHP搭配之最佳组合)admin -h `hostname` version variables shell> MySQL(和PHP搭配之最佳组合)admin -h `hostname` --port=3306 version shell> MySQL(和PHP搭配之最佳组合)admin -h ip for your host version shell> MySQL(和PHP搭配之最佳组合)admin --socket=/tmp/MySQL(和PHP搭配之最佳组合).sock version 注意hostname命令使用反引号“`”而非正引号“”；这些导致hostname输出（即，当前主机名）被代替进MySQL(和PHP搭配之最佳组合)admin命令中 。 Host ... is blocked错误 Host hostname is blocked because of many connection errors. Unblock with MySQL(和PHP搭配之最佳组合)admin flush-hosts 这意味着，MySQL(和PHP搭配之最佳组合)d已经得到了大量(max_connect_errors)的主机hostname的在中途被中断了的连接请求 。在max_connect_errors次失败请求后，MySQL(和PHP搭配之最佳组合)d认定出错了(象来字一个黑客的攻击)，并且阻止该站点进一步的连接，直到某人执行命令MySQL(和PHP搭配之最佳组合)admin flush-hosts 。 缺省地，MySQL(和PHP搭配之最佳组合)d在10个连接错误后阻塞一台主机 。你可以通过象这样启动服务器很容易地调整它： shell> safe_MySQL(和PHP搭配之最佳组合)d -O max_connect_errors=10000 & MySQL常见问题集锦之二：Too many connections错误 意味着已经有max_connections个客户连接了MySQL(和PHP搭配之最佳组合)d服务器 。 如果你需要比缺省(100)更多的连接，那么你应该重启MySQL(和PHP搭配之最佳组合)d，用更大的 max_connections 变量值 。 MySQL常见问题集锦之三：Out of memory错误 MySQL(和PHP搭配之最佳组合): Out of memory at line 42, malloc.c MySQL(和PHP搭配之最佳组合): needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) ERROR 2008: MySQL(和PHP搭配之最佳组合) client ran out of memory 注意，错误指向了MySQL(和PHP搭配之最佳组合)客户MySQL(和PHP搭配之最佳组合) 。这个错误的原因很简单，客户没有足够的内存存储全部结果 。 首先检查你的查询是否正确 MySQL常见问题集锦之四：Packet too large错误 一个MySQL(和PHP搭配之最佳组合)客户或MySQL(和PHP搭配之最佳组合)d服务器得到一个比max_allowed_packet个字节长的包 可以通过用MySQL(和PHP搭配之最佳组合) --set-variable=max_allowed_packet=8M指定一个更大的缓冲区来启动客户程序 。 MySQL常见问题集锦之五：The table is full错误 这个错误发生在内存临时表变得比tmp_table_size字节大时 。 Commands out of sync in client错误 正在以错误的次序调用客户函数！ MySQL常见问题集锦之六：Ignoring user错误 Found wrong password for user: some_user@some_host; Ignoring user 这意味着在MySQL(和PHP搭配之最佳组合)d启动时或在它再次装载权限表时，它在user表中找到了一个有一个无效口令的条目 。结果，条目简单地被权限系统忽略 。 MySQL常见问题集锦之七：Table xxx doesnt exist错误 数据库和表名件是区分大小写的！可以用SHOW TABLES检b查你在当前数据库中有哪个表 。 从一个文本文件运行SQL命令 可以把SQL命令放在一个文件中并且告诉MySQL(和PHP搭配之最佳组合)从该文件读取其输入：创造一个文本文件“text_file”，它包含要执行的命令 。然后如下调用MySQL(和PHP搭配之最佳组合)： shell> MySQL(和PHP搭配之最佳组合) database < text_file 或 shell> MySQL(和PHP搭配之最佳组合) < text_file 启动有USE db_name语句的文本文件 。 怎样重新设置一个忘记的口令 如果忘记了MySQL(和PHP搭配之最佳组合)的root用户的口令，可以使用如下方法恢复： 通过发送一个kill（不是kill -9)到MySQL(和PHP搭配之最佳组合)d服务器来关闭MySQL(和PHP搭配之最佳组合)d服务器 。pid 被保存在一个.pid文件中，通常在MySQL(和PHP搭配之最佳组合)数据库目录中： kill `cat /MySQL(和PHP搭配之最佳组合)-data-directory/hostname.pid` 你必须是一个UNIX root用户或运行服务器的相同用户做这个 。 使用--skip-grant-tables选项重启MySQL(和PHP搭配之最佳组合)d 。 用MySQL(和PHP搭配之最佳组合) -h hostname MySQL(和PHP搭配之最佳组合)连接MySQL(和PHP搭配之最佳组合)d服务器并且用一条GRANT命令改变口令 。见7.26 GRANT和REVOKE句法 。也可以用MySQL(和PHP搭配之最佳组合)admin -h hostname -u user password new password 进行 。 用MySQL(和PHP搭配之最佳组合)admin -h hostname flush-privileges或用SQL命令FLUSH PRIVILEGES来装载权限表 。 使用DATE列的问题 DATE值的格式是YYYY-MM-DD 。 改变一张表中列的顺序 在一个应用程序中，应该决不基于他们的位置使用SELECT * 检索列，因为被返回的列的顺序永远不能保证；对数据库的一个简单改变可能导致应用程序相当有戏剧性地失败 。 可以使用如下方法改变： 以正确的列顺序创建一张新表 。 执行INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table. 删除或改名old_table 。 ALTER TABLE new_table RENAME old_table 。 数据库复制 MySQL(和PHP搭配之最佳组合)(至今)没有数据库复制，但是有一些如何实现的信息 。 复制一个数据库最一般的方法是使用更新日志 。 \ 七、MYSQL的调优 \ MySQL调优\ \ 调优思路：\ 1.数据库设计与规划--以后再修该很麻烦，估计数据量，使用什么存储引擎\ 2.数据的应用--怎样取数据，sql语句的优化\ 3.mysql服务优化--内存的使用，磁盘的使用\ 4.操作系统的优化--内核、tcp连接数量\ 5.升级硬件设备\ \ \ 磁盘io规划\ raid技术：raid0[xfs]\ swap分区：最好使用raid0\ 磁盘分区：一个库放到一个分区上或一个磁盘上\ 物理分区\ create table t1(id int,name char(20)) data directory=\'/data/\' index directory =\'/data\';\ mkdir /data\ chown mysql.mysql /data\ \ mysql> show variables like \'%part%\';\ \ \ 4.操作系统的优化\ 网卡bonding技术，\ tcp连接数量限制\ 优化系统打开文件的最大限制\ 关闭操作系统不必要的服务\ \ 5.mysql服务优化\ show status 看系统的资源\ show variables 看变量，在my.cnf配置文件里定义的\ show warnings 查看最近一个sql语句产生的错误警告，看其他的需要看.err日志\ show processlist显示系统中正在运行的所有进程。\ show errors\ \ 启用mysql慢查询：---分析sql语句，找到影响效率的SQL\ \ log-slow-queries=/var/lib/mysql/slow.log 这个路径对mysql用户具有可写权限\ long_query_time=2 查询超过2秒钟的语句记录下来\ 上面的2 是查询的时间，即当一条SQL 执行时间超过5秒的时候才记录，/var/lib/mysql/slow.log 是日志记录的位置。\ 然后重新启动MySQL服务\ \ 对查询进行缓存\ query_cache_size 使用多大内存来缓存查询语句[+8M]\ mysql> show variables like\'%query%\'\ query_cache_size=8M\ [root@st mysql]# vim /etc/my.cnf\ \ \ mysql> show status like \'%Qcache%\';\ Qcache_free_blocks：说明缓存太大了。缓存中相邻内存的个数。数目大说明可能有碎片。FLUSH QUERY CACHE会对缓存中的碎片进行整理，从而得到一个空闲块。[+8M]\ Qcache_free_memory缓存中的空闲内存\ Qcache_hits每次查询在缓存中命中时就增大\ Qcache_inserts每插入一个查询时就增大。命中次数除以插入次数就是命中率。\ Qcache_lowmen_prunes缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间看；如果这个数字在不断增长就表示可能碎片非常严重，或者内存很少\ Qcache_hits/Qcache_inserts 命中率\ \ 关键字缓冲区\ mysql> show status like \'%key%\';\ mysql> show variables like\'key_buffer_size\';\ \ key_buffer_size 指定索引缓冲区的大小，它决定索引处理的速度，尤其是索引读的速度。[+8M]\ key_read_requests 请求总数\ key_reads 代表命中磁盘的请求个数\ (key_read_requests-key_read)/key_read_requests：命中率\ key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表，但是内部的临时磁盘表是MyISAM表，也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。\ 对于1G内存的机器，如果不使用MyISAM表，推荐值是16M（8-64M）。\ \ 临时表空间大小：order by和group by时把数据放到临时表里。\ tmp_table_size 占的是内存的大小，如果太小在排序时会出错\ created_tmp_tables 创建临时表的数量\ max_tmp_tables=32\ tmpdir=/tmp 硬盘上临时表所在的位置\ \~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\ innodb表：\ 创建表空间文件\ [mysqld]\ innodb_data_file_path=ibdata1:10M:autoextend\ 这个设置配置一个可扩展大小的尺寸为10MB的单独文件，名为ibdata1。没有给出文件的位置，所以默认的是在MySQL的数据目录内。\ 如果你对最后的数据文件指定autoextend选项。如果数据文件耗尽了表空间中的自由空间，InnoDB就扩展数据文件。扩展的幅度是每次8MB。\ 要为一个自动扩展数据文件指定最大尺寸，请使用max属性。下列配置允许ibdata1涨到极限的500MB：\ [mysqld]\ innodb_data_file_path=ibdata1:10M:autoextend:max:500M\ InnoDB默认地在MySQL数据目录创建表空间文件。要明确指定一个位置，请使用innodb_data_home_dir选项。比如，要使用两个名为ibdata1和ibdata2的文件，但是要把他们创建到/ibdata，像如下一样配置InnoDB：\ [mysqld]\ innodb_data_home_dir = /ibdata\ innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend\ \ mysql> show variables like \'innodb_buffer_pool_size\';\ innodb_buffer_pool_size\ 对于InnoDB表来说，innodb_buffer_pool_size的作用就相当于key_buffer_size对于MyISAM表的作用一样。InnoDB使用该参数指定大小的内存来缓冲数据和索引。对于单独的MySQL数据库服务器，最大可以把该值设置成物理内存的80%。\ 根据MySQL手册，对于2G内存的机器，推荐值是1G（50%）。\ \ mysql> show variables like \'innodb_%per%\';［建议打开］\ innodb_file_per_table =1 为每一个表单独创建一个表空间文件。\ 其他参数\ skip-locking\ 取消文件系统的外部锁，减少出错几率增强稳定性\ \ skip-name-resolve\ 关闭mysql的dns反查功能。这样速度就快了!\ 选项就能禁用DNS解析，连接速度会快很多。不过，这样的话就不能在MySQL的授权表中使用主机名了而只能用ip格式。\ \ wait_timeout=10 终止空闲时间超过10秒的链接，避免长连接［默认8个小时］\ \ max_connect_errors=10 //10次连接失败就锁定，使用flush hosts 解锁，\ 或mysqladmin flush-hosts解锁\ \ \~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\ SQL语句调优：\ explain命令：查询select。\ .type\ 这列很重要,显示了连接使用了哪种类别,有无使用索引\ 从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL\ \ MySQL性能诊断与调优 LAMP 系统性能调优，第 3 部分: MySQL 服务器调优\ https://www.ibm.com/developerworks/cn/linux/l-tune-lamp-3.html LoadRunner监控MySQL\ https://www.docin.com/p-92272846.html Advanced MySQL Performance Optimization\ https://www.mysqlperformanceblog.com/files/presentations/UC2005-Advanced-MySQL- Performance-Optimization.pdf Improving MySQL Server Performance with Intel C++ Compiler\ https://www.mysqlperformanceblog.com/files/presentations/LinuxWorld2005-Intel.pdf MySQL性能诊断与调优相关工具：\ https://www.mysqlperformanceblog.com/tools/\ https://hackmysql.com/mysqlreport Spotlight On MySQL:\ https://www.quest.com/spotlight-on-mysql/ Mysql Administator https://downloads.mysql.com/archives.php?p=MySQLAdministrationSuite phpMyAdmin https://www.phpmyadmin.net/home_page/index.php mysql slow log分析工具\ https://hackmysql.com/\ https://www.willamowius.de/mysql-tools.html\ https://code.google.com/p/mysql-log-filter/\ https://myprofi.sourceforge.net/ mysql网络协议嗅探工具 - mysqlsniffer https://hackmysql.com/mysqlsniffer MySQL性能诊断与调优相关书籍：\ 《High Performance MySQL Second Edition》 优化mysql数据库性能的十个参数\ (1)、max_connections：\ 允许的同时客户的数量。增加该值增加 mysqld 要求的文件描述符的数量。这个数字应该增加，否则，你将经常看到 too many connections 错误。 默认数值是100，我把它改为1024 。\ (2)、record_buffer：\ 每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描，你可能想要增加该值。默认数值是131072(128k)，我把它改为16773120 (16m)\ (3)、key_buffer_size：\ 索引块是缓冲的并且被所有的线程共享。key_buffer_size是用于索引块的缓冲区大小，增加它可得到更好处理的索引(对所有读和多重写)，到你能负担得起那样多。如果你使它太大，系统将开始换页并且真的变慢了。默认数值是8388600(8m)，我的mysql主机有2gb内存，所以我把它改为 402649088(400mb)。\ 4)、back_log：\ 要求 mysql 能有的连接数量。当主要mysql线程在一个很短时间内得到非常多的连接请求，这就起作用，然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。\ back_log 值指出在mysql暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接，你需要增加它，换句话说，这值对到来的tcp/ip连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定back_log高于你的操作系统的限制将是无效的。\ 当你观察你的主机进程列表，发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | null | connect | null | login | null 的待连接进程时，就要加大 back_log 的值了。默认数值是50，我把它改为500。\ (5)、interactive_timeout：\ 服务器在关闭它前在一个交互连接上等待行动的秒数。一个交互的客户被定义为对 mysql_real_connect()使用 client_interactive 选项的客户。 默认数值是28800，我把它改为7200。\ (6)、sort_buffer：\ 每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速order by或group by操作。默认数值是2097144(2m)，我把它改为 16777208 (16m)。\ (7)、table_cache：\ 为所有线程打开表的数量。增加该值能增加mysqld要求的文件描述符的数量。mysql对每个唯一打开的表需要2个文件描述符。默认数值是64，我把它改为512。\ (8)、thread_cache_size：\ 可以复用的保存在中的线程的数量。如果有，新的线程从缓存中取得，当断开连接的时候如果有空间，客户的线置在缓存中。如果有很多新的线程，为了提高性能可以这个变量值。通过比较 connections 和 threads_created 状态的变量，可以看到这个变量的作用。我把它设置为 80。\ (9)mysql的搜索功能\ 用mysql进行搜索，目的是能不分大小写，又能用中文进行搜索\ 只需起动mysqld时指定 --default-character-set=gb2312\ (10)、wait_timeout：\ 服务器在关闭它之前在一个连接上等待行动的秒数。 默认数值是28800，我把它改为7200。\ 注：参数的调整可以通过修改 /etc/my.cnf 文件并重启 mysql 实现。这是一个比较谨慎的工作，上面的结果也仅仅是我的一些看法，你可以根据你自己主机的硬件情况（特别是内存大小）进一步修改。 \ \ 八、MYSQL主主、主从复制的实现 \ 见SVN文档 \ 九、MYSQL大数据备份和恢复 \ 见SVN文档 \ 十、数据文件的损坏与修复 1. 表损坏的原因分析\ 以下原因是导致mysql 表毁坏的常见原因：\ 1、 服务器突然断电导致数据文件损坏。\ 2、 强制关机，没有先关闭mysql 服务。\ 3、 mysqld 进程在写表时被杀掉。\ 4、 使用myisamchk 的同时，mysqld 也在操作表。\ 5、 磁盘故障。\ 6、 服务器死机。\ 7、 mysql 本身的bug 。\ 2. 表损坏的症状\ 一个损坏的表的典型症状如下：\ 1 、当在从表中选择数据之时，你得到如下错误：\ Incorrect key file for table: \'...\'. Try to repair it\ 2 、查询不能在表中找到行或返回不完全的数据。\ 3 、Error: Table \'p\' is marked as crashed and should be repaired 。\ 4 、打开表失败： Can't open file: ‘×××.MYI' (errno: 145) 。\ 5 、\ 3. 预防 MySQL表损坏\ 可以采用以下手段预防mysql 表损坏：\ 1 、定期使用myisamchk 检查MyISAM 表（注意要关闭mysqld ），推荐使用check table 来检查表（不用关闭mysqld ）。\ 2 、在做过大量的更新或删除操作后，推荐使用OPTIMIZE TABLE 来优化表，这样既减少了文件碎片，又减少了表损坏的概率。\ 3 、关闭服务器前，先关闭mysqld （正常关闭服务，不要使用kill -9 来杀进程）。\ 4 、使用ups 电源，避免出现突然断电的情况。\ 5 、使用最新的稳定发布版mysql ，减少mysql 本身的bug 导致表损坏。\ 6 、对于InnoDB 引擎，你可以使用innodb_tablespace_monitor 来检查表空间文件内文件空间管理的完整性。\ 7 、对磁盘做raid ，减少磁盘出错并提高性能。\ 8 、数据库服务器最好只跑mysqld 和必要的其他服务，不要跑其他业务服务，这样减少死机导致表损坏的可能。\ 9 、不怕万一，只怕意外，平时做好备份是预防表损坏的有效手段。\ 4. MySQL表损坏的修复\ MyISAM 表可以采用以下步骤进行修复 ：\ 1、 使用 reapair table 或myisamchk 来修复。\ 2、 如果上面的方法修复无效，采用备份恢复表。\ 具体可以参考如下做法：\ 阶段1 ：检查你的表\ 如果你有很多时间，运行myisamchk *.MYI 或myisamchk -e *.MYI 。使用-s （沉默）选项禁止不必要的信息。\ 如果mysqld 服务器处于宕机状态，应使用--update-state 选项来告诉myisamchk 将表标记为\' 检查过的\' 。\ 你必须只修复那些myisamchk 报告有错误的表。对这样的表，继续到阶段2 。\ 如果在检查时，你得到奇怪的错误( 例如out of memory 错误) ，或如果myisamchk 崩溃，到阶段3 。\ 阶段2 ：简单安全的修复\ 注释：如果想更快地进行修复，当运行myisamchk 时，你应将sort_buffer_size 和Key_buffer_size 变量的值设置为可用内存的大约25% 。\ 首先，试试myisamchk -r -q tbl_name(-r -q 意味着“ 快速恢复模式”) 。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接，这应该管用并且表可被修复。开始修复下一张表。否则，执行下列过程：\ 在继续前对数据文件进行备份。\ 使用myisamchk -r tbl_name(-r 意味着“ 恢复模式”) 。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。\ 如果前面的步骤失败，使用myisamchk --safe-recover tbl_name 。安全恢复模式使用一个老的恢复方法，处理常规恢复模式不行的少数情况( 但是更慢) 。\ 如果在修复时，你得到奇怪的错误( 例如out of memory 错误) ，或如果myisamchk 崩溃，到阶段3 。\ 阶段3 ：困难的修复\ 只有在索引文件的第一个16K 块被破坏，或包含不正确的信息，或如果索引文件丢失，你才应该到这个阶段。在这种情况下，需要创建一个新的索引文件。按如下步骤操做：\ 把数据文件移到安全的地方。\ 使用表描述文件创建新的( 空) 数据文件和索引文件：\ shell> mysql db_name\ mysql> SET AUTOCOMMIT=1;\ mysql> TRUNCATE TABLE tbl_name;\ mysql> quit\ 如果你的MySQL 版本没有TRUNCATE TABLE ，则使用DELETE FROM tbl_name 。\ 将老的数据文件拷贝到新创建的数据文件之中。（不要只是将老文件移回新文件之中；你要保留一个副本以防某些东西出错。）\ 回到阶段2 。现在myisamchk -r -q 应该工作了。（这不应该是一个无限循环）。\ 你还可以使用REPAIR TABLE tbl_name USE_FRM ，将自动执行整个程序。\ 阶段4 ：非常困难的修复\ 只有.frm 描述文件也破坏了，你才应该到达这个阶段。这应该从未发生过，因为在表被创建以后，描述文件就不再改变了。\ 从一个备份恢复描述文件然后回到阶段3 。你也可以恢复索引文件然后回到阶段2 。对后者，你应该用myisamchk -r 启动。\ 如果你没有进行备份但是确切地知道表是怎样创建的，在另一个数据库中创建表的一个拷贝。删除新的数据文件，然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件，但是让.MYD 数据文件独自留下来了。回到阶段2 并且尝试重建索引文件。\ InnoDB 表可以采用下面的方法修复：\ 如果数据库页被破坏，你可能想要用SELECT INTO OUTFILE 从从数据库转储你的表，通常以这种方法获取的大多数数据是完好的。即使这样，损坏可能导致SELECT * FROM tbl_name 或者InnoDB 后台操作崩溃或断言，或者甚至使得InnoDB 前滚恢复崩溃。 尽管如此，你可以用它来强制InnoDB 存储引擎启动同时阻止后台操作运行，以便你能转储你的表。例如：你可以在重启服务器之前，在选项文件的[mysqld] 节添加如下的行：\ [mysqld]innodb_force_recovery = 4innodb_force_recovery 被允许的非零值如下。一个更大的数字包含所有更小数字的预防措施。如果你能够用一个多数是4 的选项值来转储你的表，那么你是比较安全的，只有一些在损坏的单独页面上的数据会丢失。一个为6 的值更夸张，因为数据库页被留在一个陈旧的状态，这个状态反过来可以引发对B 树和其它数据库结构的更多破坏。\ 1 (SRV_FORCE_IGNORE_CORRUPT)\ 即使服务器检测到一个损坏的页，也让服务器运行着；试着让SELECT * FROM tbl_name 跳过损坏的索引记录和页，这样有助于转储表。\ 2 (SRV_FORCE_NO_BACKGROUND)\ 阻止主线程运行，如果崩溃可能在净化操作过程中发生，这将阻止它。\ 3 (SRV_FORCE_NO_TRX_UNDO)\ 恢复后不运行事务回滚。\ 4 (SRV_FORCE_NO_IBUF_MERGE)\ 也阻止插入缓冲合并操作。如果你可能会导致一个崩溃。最好不要做这些操作，不要计算表统计表。\ 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)\ 启动数据库之时不查看未完成日志：InnoDB 把未完成的事务视为已提交的。\ 6 (SRV_FORCE_NO_LOG_REDO)\ 不要在恢复连接中做日志前滚。\ 数据库不能另外地带着这些选项中被允许的选项来使用。作为一个安全措施，当innodb_force_recovery 被设置为大于0 的值时，InnoDB 阻止用户执行INSERT, UPDATE 或DELETE 操作.\ 即使强制恢复被使用，你也可以DROP 或CREATE 表。如果你知道一个给定的表正在导致回滚崩溃，你可以移除它。你也可以用这个来停止由失败的大宗导入或失败的ALTER TABLE 导致的失控回滚。你可以杀掉mysqld 进程，然后设置innodb_force_recovery 为3 ，使得数据库被挂起而不需要回滚，然后舍弃导致失控回滚的表。\ [\ ] 文章作者 明哥 文章地址 https://www.pvcreate.com/index.php/archives/83/ 创建时间 2015-06-01 关注订阅 微信订阅号 开源项目 https://gitee.com/lookingdreamer 工具市场 https://gitee.com/lookingdreamer/SPPPOTools