MySQL 拷贝一个InnoDB分区表到另一个实例

拷贝一个InnoDB分区表到另一个实例
这个过程演示了如何将一个InnoDB分区表从一个正在运行的MySQL服务器实例复制到另一个正在运行的实例。同样的过程,只要稍微做些调整,就可以在同一个实例上对InnoDB分区表执行完全恢复。

1.在源实例上,如果不存在分区表,则创建分区表。在下面的例子中,创建了一个包含三个分区(p0, p1, p2)的表

mysql> use test;
Database changed
mysql> create table t1(i int) engine=innodb partition by key(i) partitions 3;
Query OK, 0 rows affected (0.38 sec)

mysql> insert into t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9);
Query OK, 9 rows affected (0.03 sec)
Records: 9  Duplicates: 0  Warnings: 0
mysql> select * from t1;
+------+
| i    |
+------+
|    4 |
|    5 |
|    1 |
|    6 |
|    7 |
|    2 |
|    3 |
|    8 |
|    9 |
+------+
9 rows in set (0.00 sec)

在/mysqldata/mysql/test目录中,对于三个分区都有一个单独的表空间(.ibd)文件:

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 304
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:43 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p0.ibd

2.在目标实例上,创建相同的分区表:

mysql> use test;
Database changed
mysql> create table t1(i int) engine=innodb partition by key(i) partitions 3;
Query OK, 0 rows affected (0.20 sec)

在/mysqldata/mysql/test目录中,对于三个分区都有一个单独的表空间(.ibd)文件:

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 304
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:45 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:45 t1#P#p2.ibd

3.在目标实例上,丢弃分区表的表空间。(在将表空间导入目标实例之前,必须丢弃附加到接收表的表空间。)

mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected (0.09 sec)

组成分区表表空间的三个.ibd文件从/mysqldata/mysql/tes目录中被丢弃,留下以下文件

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 16
-rw-r-----. 1 mysql mysql   67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql 8554 3月  16 15:45 t1.frm

4.在源实例上,运行FLUSH TABLES… FOR EXPORT用于暂停分区表并创建.cfg元数据文件

mysql> flush tables t1 for export;
Query OK, 0 rows affected (0.01 sec)

在源实例的/mysqldata/mysql/test目录中创建元数据(.cfg)文件,每个表空间(.ibd)文件对应一个元数据文件

[root@localhost ~]# cd /mysqldata/mysql/test
[root@localhost test]# ls -lrt
总用量 316
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:43 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 15:43 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p1.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p0.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:00 t1#P#p2.cfg

FLUSH TABLES……FOR EXPORT语句确保对指定表的更改已刷新到磁盘,以便在实例运行时可以进行二进制表拷贝。当运行FLUSH TABLES … FOR EXPORT时,InnoDB会在数据库目录中为表的表空间文件生成一个.cfg元数据文件。.cfg文件中包含导入表空间文件时验证模式的元数据。FLUSH TABLES … FOR EXPORT只能在表上运行,而不能在单独的表分区上运行。

5.将.ibd和.cfg文件从源实例数据库目录复制到目标实例数据库目录。例如

[root@localhost test]# scp t1*.{ibd,cfg} mysql@192.168.1.243:/mysqldata/mysql/test/
mysql@192.168.1.243's password:
t1#P#p0.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p1.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p2.ibd                                                                                                                                                                                              100%   96KB  96.0KB/s   00:00
t1#P#p0.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
t1#P#p1.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
t1#P#p2.cfg                                                                                                                                                                                              100%  375     0.4KB/s   00:00
[root@localhost test]#

[root@localhost test]# ls -lrt
总用量 316
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8554 3月  16 15:45 t1.frm
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p0.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p1.ibd
-rw-r-----. 1 mysql mysql 98304 3月  16 16:06 t1#P#p2.ibd
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p0.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p1.cfg
-rw-r-----. 1 mysql mysql   375 3月  16 16:06 t1#P#p2.cfg

6.在源实例上,使用unlock tables语句来释放由flush tables … for export所获取的锁:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

在源实例上释放锁时,会向mysql日志文件写入删除.cfg文件的信息:

2022-03-16T08:08:27.653352Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p0.cfg'
2022-03-16T08:08:27.653656Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p1.cfg'
2022-03-16T08:08:27.654214Z 10 [Note] InnoDB: Deleting the meta-data file './test/t1#P#p2.cfg'
2022-03-16T08:08:27.654256Z 10 [Note] InnoDB: Resuming purge

7.在目标实例上,导入表空间:

mysql> select * from t1;
ERROR 1814 (HY000): Tablespace has been discarded for table 't1'
mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected (0.09 sec)

mysql> alter table t1 import tablespace;
Query OK, 0 rows affected (0.46 sec)

mysql> select * from t1;
+------+
| i    |
+------+
|    4 |
|    5 |
|    1 |
|    6 |
|    7 |
|    2 |
|    3 |
|    8 |
|    9 |
+------+
9 rows in set (0.01 sec)

MySQL 传输表空间

将file-per-table表空间复制到另一个实例
如何将一个file-per-table表空间从一个MySQL实例复制到另一个实例中,也就是众所周知的可传输表空间特性。

有很多原因可以解释为什么你可以将一个InnoDB文件表空间复制到不同的实例中:
.在不增加生产服务器额外负载的情况下运行报表。

.在新的从服务器上为表设置相同的数据

.在出现问题或错误后恢复表或分区的备份版本。

.作为一种比mysqldump命令导入更快的移动数据的方法。数据立即可用,而不需要重新插入和重建索引

.将每个file-per-table表空间移动到具有更适合系统需求的存储介质的服务器。例如,您可能希望在SSD设备上有繁忙的表,或者在高容量HDD设备上有大型表。

限制和使用说明
.只有当innodb_file_per_table设置为ON(默认设置)时,才可以拷贝表空间。驻留在共享系统表空间中的表不能被静默。

.当一个表被静默时,只允许在受影响的表上执行只读事务

.在导入表空间时,页面大小必须与导入实例的页面大小相匹配。

.当foreign_key_checks设置为1时,对于父-子(主-外键)关系的表空间不支持DISCARD TABLESPACE。在丢弃父-子表的表空间之前,设置foreign_key_checks=0。分区InnoDB表不支持外键。

.ALTER TABLE……IMPORT TABLESPACE不会对导入的数据强制外键约束。如果表之间存在外键约束,那么所有表都应该在同一(逻辑)时间点导出。分区InnoDB表不支持外键。

.ALTER TABLE……IMPORT TABLESPACE 和 ALTER TABLE…IMPORT PARTITION…TABLESPACE不需要.cfg元数据文件来导入一个表空间。但是,如果导入时没有.cfg文件,则不会执行元数据检查,并且会发出类似于下面的警告:

Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\
test\t.cfg', will attempt to import without schema verification
1 row in set (0.00 sec)

在期待没用模式不匹配的情况下,不使用.cfg文件进行导入可能会更方便。此外,在无法从.ibd文件收集元数据的崩溃恢复场景中,不需要.cfg文件就可以导入。

.由于.cfg元数据文件的限制,当为分区表导入表空间文件时,不会对分区类型或分区定义差异报告模式不匹配。列差异被报告。

.当在子分区表上运行ALTER TABLE … DISCARD PARTITION … TABLESPACE和ALTER TABLE … IMPORT PARTITION … TABLESPACE,分区和子分区表名都是允许的。当指定分区名时,该分区的子分区将包含在操作中。

.如果两个实例都有GA(通用可用性)状态,并且它们的版本在同一系列可以从另一个MySQL服务器实例导入表空间文件。否则,该文件必须是在导入它的同一个服务器实例上所创建

.在复制场景中,innodb_file_per_table必须在主节点和从节点上都设置为ON。

.在Windows环境下,InnoDB内部存储数据库、表空间和表名时使用小写字母。为了避免在区分大小写的操作系统(如Linux、UNIX)上的导入问题,请在创建数据库、表空间和表时使用小写名称。一种方便的方法是在创建数据库、表空间或表之前,在my.cnf或my.ini文件的[mysqld]部分中添加下面这一行:

[mysqld]
lower_case_table_names=1

.alter table … discard tablespace和alter table … import tabelspace不支持属于InnoDB通用表空间中的表。

.InnoDB表的默认行格式可以通过innodb_default_row_format配置选项进行配置。如果导入的表没有明确定义行格式(ROW_FORMAT),或者使用了ROW_FORMAT=DEFAULT,那么如果源实例上的innodb_default_row_format设置与目标实例上的innodb_default_row_format设置不一致,可能会导致模式不匹配错误

.在使用InnoDB表空间加密特性导出加密的表空间时,InnoDB除了生成一个.cfg元数据文件外,还会生成一个.cfp文件。在目标实例上执行ALTER TABLE…IMPORT TABLESPACE之前,必须将.cfp文件与.cfg文件和表空间文件一起复制到目标实例中。cfp文件包含一个传输密钥和一个加密的表空间密钥。在导入时,InnoDB使用传输密钥来解密表空间密钥。

传输表空间示例
例如1:复制一个InnoDB表到另一个实例
这个过程演示了如何将一个普通的InnoDB表从一个正在运行的MySQL服务器实例复制到另一个正在运行的实例。可以使用相同的过程在相同的实例上执行全表恢复,只是做了一些小小的调整。
1. 在源实例上,如果不存在表,则创建一个表:

mysql> use test;
Database changed
mysql> create table t(c1 int) engine=innodb;
Query OK, 0 rows affected (0.12 sec)

mysql> insert into t values(1);
Query OK, 1 row affected (0.16 sec)

2.在目标实例上,如果不存在表,则创建表:

mysql> use test;
Database changed
mysql> create table t(c1 int) engine=innodb;
Query OK, 0 rows affected (0.09 sec)

3.在目标实例上,丢弃现有的表空间。(在导入表空间之前,InnoDB必须丢弃连接到接收表空间的表空间。)

[mysql@localhost test]$ ls -lrt
总用量 112
-rw-r-----. 1 mysql mysql    67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql  8556 3月  15 16:57 t.frm
-rw-r-----. 1 mysql mysql 98304 3月  15 16:57 t.ibd

mysql> alter table t discard tablespace;
Query OK, 0 rows affected (0.17 sec)



[mysql@localhost test]$ ls -lrt
总用量 16
-rw-r-----. 1 mysql mysql   67 3月  15 16:55 db.opt
-rw-r-----. 1 mysql mysql 8556 3月  15 16:57 t.frm

4.在源实例上,运行FLUSH TABLES…FOR EXPORT将暂停表并创建.cfg元数据文件

mysql> flush tables t for export;
Query OK, 0 rows affected (0.00 sec)


[mysql@localhost test]$ ls -lrt
总用量 116
-rw-r-----. 1 mysql mysql    67 3月  15 16:53 db.opt
-rw-r-----. 1 mysql mysql  8556 3月  15 16:54 t.frm
-rw-r-----. 1 mysql mysql 98304 3月  15 16:54 t.ibd
-rw-r-----. 1 mysql mysql   371 3月  15 17:00 t.cfg

在InnoDB数据目录下创建元数据(.cfg)
注意:FLUSH TABLES …… FOR EXPORT在MySQL 5.6.6版本中可用。该语句确保对指定表的更改已刷新到磁盘,以便在实例运行时可以生成二进制表副本。当FLUSH TABLES … FOR EXPORT时,InnoDB会在表所在的数据库目录中生成一个.cfg文件。cfg文件中包含导入表空间文件时用于模式验证的元数据。

5.将.ibd文件和.cfg元数据文件从源实例复制到目标实例

[mysql@localhost test]$ scp t.{ibd,cfg} mysql@192.168.1.243:/mysqldata/mysql/test/
mysql@192.168.1.243's password:
t.ibd                                                                                                                                                                                                    100%   96KB  96.0KB/s   00:00
t.cfg                                                                                                                                                                                                    100%  371     0.4KB/s   00:00
[mysql@localhost test]$

在释放共享锁之前必须复制.ibd与.cfg文件。

6.在源实例上,使用unlock tables语句来释放由flush tables … for export所获取的锁:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

7.在目标实例上,导入表空间:
mysql> alter table t import tablespace;
Query OK, 0 rows affected (0.15 sec)

mysql> desc t;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| c1    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from t;
+------+
| c1   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

可以看到表t从一个实例迁移到另一个实例上。

MySQL InnoDB File-Per-Table表空间

InnoDB File-Per-Table表空间
过去,所有InnoDB表和索引都存储在系统表空间中。这种整体的方法针对的是完全专用于数据库处理的机器,通过精心规划的数据增长,分配给MySQL的任何磁盘存储永远不会被用于其他用途。InnoDB的file-per-table表空间特性提供了一个更灵活的替代方案,每个InnoDB表及其索引都存储在一个单独的.ibd数据文件中。每个这样的.ibd数据文件代表一个单独的表空间。这个特性是由innodb_file_per_table配置选项控制的,在MySQL 5.6.6及更高版本中默认启用。

file-per-table表空间的优点
.当truncate或drop存储在file-per-table表空间中的表时,可以回收磁盘空间。truncate或drop存储在共享系统表空间中的表会在系统表空间数据文件(ibdata文件)内部创建空闲空间,这些空间只能用于新的InnoDB数据。

.在存储在file-per-table表空间文件中的表上运行TRUNCATE TABLE操作会更快。

.您可以将特定的表存储在单独的存储设备上,以实现I/O优化、空间管理或备份目的。在以前的版本中,您必须将整个数据库目录移动到其他驱动器,并在MySQL数据目录中创建符号链接。在MySQL 5.6.6及更高版本中,你可以使用
create table… data directory=absolute_path_to_directory。

.你可以运行OPTIMIZE TABLE来压缩或重新创建一个file-per-table表空间。当你运行一个OPTIMIZE TABLE时,InnoDB会创建一个新的.ibd文件,该文件带有一个临时名称,只使用存储实际数据所需的空间。当优化完成后,InnoDB会删除旧的.ibd文件,并用新文件替换它。如果以前的.ibd文件显著增长,但实际数据只占其大小的一部分,那么运行OPTIMIZE TABLE可以回收未使用的空间。

.你可以移动单个InnoDB表,而不是整个数据库

.你可以将InnoDB表从一个MySQL实例复制到另一个实例(称为可迁移表空间特性)。

.在file-per-table表空间中创建的表使用Barracuda文件格式。Barracuda文件格式支持压缩和动态行格式等特性

.可以使用动态行格式为具有大型BLOB或TEXT列的表启用更高效的存储。

.file-per-table表空间可以在发生损坏、服务器无法重启或备份和二进制日志不可用时提高成功恢复的机会并节省时间。

.在复制或备份表时,file-per-table表空间可以方便地报告每个表的状态。

.可以在文件系统级别监控表大小,而不需要访问MySQL。

.当innodb_flush_method设置为O_DIRECT时,普通的Linux文件系统不允许并发写入单个文件。因此,使用file-per-table表空间和innodb_flush_method可能会提高性能。

.系统表空间存储数据字典和undo日志,受InnoDB表空间大小限制。使用file-per_table表空间,每个表都有自己的表空间,这为增长提供了空间。

file-per-table表空间的潜在缺点
.使用file-per-table表空间,每个表可能有未使用的空间,这些空间只能由同一表的行使用。如果管理不当,可能会造成空间的浪费。

.fsync操作必须在每个打开的表上运行,而不是单个文件上。因为每个文件都有一个单独的fsync操作,所以对多个表的写操作不能合并成一个单独的I/O操作。这可能需要InnoDB执行更多的fsync操作。

.mysqld必须为每个表保留一个打开的文件句柄,如果在file-per-table表空间中有很多表,这可能会影响性能。

.使用了更多的文件描述符

.innodb_file_per_table在MySQL 5.6.6及更高版本中是默认启用的。如果向后兼容MySQL 5.5或5.1是一个问题,你可以考虑禁用它。禁用innodb_file_per_table功能可以防止在ALTER TABLE重新创建InnoDB表(ALGORITHM=COPY)时,阻止alter table将InnoDB表从系统表空间移动到单独的.ibd文件中。

例如,当重构InnoDB表的聚集索引时,表会使用innodb_file_per_table的当前设置重新创建。此行为在添加或删除InnoDB二级索引时不适用。当不重建表而创建二级索引时,无论当前的innodb_file_per_table设置是什么,索引都被存储在与表数据相同的文件中。此行为也不适用于使用CREATE TABLE…TABLESPACE或ALTER TABLE …TABLESPACE语法添加到系统表空间中的表。这些表不受innodb_file_per_table设置的影响。

.如果许多表都在增长,可能会出现更多的碎片,这可能会影响DROP TABLE和表扫描性能。但是,在管理碎片时,将文件放在它们自己的表空间中可以提高性能。

.在删除file-per-table表空间时会扫描缓冲池,对于大小为几十gb的缓冲池来说,这可能需要几秒钟的时间。扫描是用一个宽的内部锁执行的,这可能会延迟其他操作。系统表空间中的表不受影响。

.innodb_autoextend_increment变量定义了自动扩展的共享表空间文件满时的扩展大小(以MB为单位),但不适用于file-per-table表空间文件,不管是否设置了innodb_autoextend_increment,这些文件都是自动扩展的。最初的扩展是少量的,之后扩展以4MB的增量出现。

启用与禁用file-per-table表空间
innodb_file_per_table选项默认是启用的。

为了在启动时设置innodb_file_per_table选项,可以在启动服务时使用–innodb_file_per_table命令行选项或者在my.cnf文件中[mysqld]部分增加以下一行内容:

[mysqld]
innodb_file_per_table=1

你也可以在服务器运行时动态设置innodb_file_per_table:

mysql> SET GLOBAL innodb_file_per_table=1;
Query OK, 0 rows affected (0.00 sec)

启用innodb_file_per_table时,可以将InnoDB表存储在tbl_name.ibd文件。不像MyISAM存储引擎,它有单独的tbl_name.MYD和tbl_name.MYI文件用于索引和数据,InnoDB将数据和索引一起存储在一个.ibd文件中。仍然像往常一样创建tbl_name.frm文件。

如果在启动选项中禁用innodb_file_per_table并重启服务器或者使用set global命令来禁用它,除非你显式的使用create table … tablespace选项将表存放在file-per-table表空间或通用表空间否则innodb将在系统表空间创建新表。

你总是可以读取和写入任何InnoDB表,不管file-per-table设置情况。

如果要将表从系统表空间移动到自己的表空间,需要修改innodb_file_per_table的设置,然后重新创建表:

mysql> SET GLOBAL innodb_file_per_table=1;
mysql> ALTER TABLE table_name ENGINE=InnoDB;

使用CREATE TABLE…TABLESPACE或ALTER TABLE…TABLESPACE语法添加表到系统表空间不受innodb_file_per_table设置的影响。要将这些表从系统表空间移动到file-per-table表空间,必须使用ALTER TABLE…TABLESPACE语法。

InnoDB总是需要系统表空间,因为它把它的内部数据字典和undo日志放在那里。.ibd文件不够InnoDB操作。

当一个表从系统表空间移到它自己的.ibd文件时,组成系统表空间的数据文件保持相同的大小。InnoDB表以前占用的空间可以被新的InnoDB数据重用,但是不会被操作系统回收使用。当将较大的InnoDB表移出系统表空间(磁盘空间有限)时,你可能更喜欢启用innodb_file_per_table并使用mysqldump命令重新创建整个实例。如上所述,使用CREATE TABLE…TABLESPACE或者ALTER TABLE…表空间语法不受innodb_file_per_table设置的影响。这些桌子必须单独移动。

在数据目录外创建逐file-per-table表空间
要在MySQL数据目录之外的特定位置创建一个新的InnoDB file-per-table表空间,使用有data directory = absolute_path_to_directory子句的CREATE TABLE语句的来实现。

提前计划位置,因为您不能在ALTER TABLE语句中使用DATA DIRECTORY子句。您指定的目录可以位于具有特定性能或容量特征的另一个存储设备上,例如快速SSD或大容量HDD。

在目标目录中,MySQL创建一个与数据库名称对应的子目录,在该子目录中为新表创建一个.ibd文件。在MySQL DATADIR目录下的数据库目录中,MySQL创建了一个table_name.Isl文件包含表路径名。.isl文件被MySQL视为一个符号链接。(InnoDB表不支持使用实际的符号链接。)

下面的例子演示了如何在MySQL数据目录外创建一个file-per-table表空间。它显示了在指定目录中创建的.ibd,以及在MySQL数据目录下的数据库目录中创建的.isl。

mysql> use mysql
Database changed
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)


mysql> create table t_cs(c1 int primary key) data directory='/data';
Query OK, 0 rows affected (0.22 sec)


[root@localhost mysql]# pwd
/data/mysql
[root@localhost mysql]# ls -lrt
总用量 96
-rw-r-----. 1 mysql mysql 98304 3月   8 16:09 t_cs.ibd

[root@localhost mysql]# ls -lrt t_cs*
-rw-r-----. 1 mysql mysql 8556 3月   8 16:09 t_cs.frm
-rw-r-----. 1 mysql mysql   20 3月   8 16:09 t_cs.isl

你也可以使用CREATE TABLE…TABLESPACE与DATA DIRECTORY子句结合,在MySQL数据目录之外创建一个file-per-table表空间。为此,你必须指定innodb_file_per_table作为表空间名。

mysql> create table t_cs_3(c1 int primary key) tablespace=innodb_file_per_table data directory='/data';
Query OK, 0 rows affected (0.28 sec)

[root@localhost mysql]# ls -lrt t_cs_2*
-rw-r-----. 1 mysql mysql 98304 3月   8 16:14 t_cs_2.ibd

[root@localhost mysql]# ls -lrt t_cs_2*
-rw-r-----. 1 mysql mysql 8556 3月   8 16:14 t_cs_2.frm
-rw-r-----. 1 mysql mysql   22 3月   8 16:14 t_cs_2.isl

使用这个方法时,你不需要启用innodb_file_per_table。

使用说明:
.MySQL最初保存的.ibd文件是打开的,防止您卸载设备,但如果服务器繁忙,可能最终会关闭表。小心不要在MySQL运行时意外地卸载外部设备,或者在设备断开连接时启动MySQL。当关联的.ibd文件丢失时,试图访问表会导致严重错误,需要重新启动服务器。

如果.ibd文件仍然不在预期的路径上,服务器重启可能会失败。在本例中,手动删除数据库目录中的table_name.isl文件重新启动后,执行DROPTABLE命令删除.frm文件,并从数据字典中删除该表的信息。

.在将表存放在NFS挂载的卷上之前,请查看在使用NFS和MySQL中列出的潜在问题。

.如果您使用LVM快照、文件复制或其他基于文件的机制来备份.ibd文件,请始终使用FLUSH TABLES…FOR EXPORT语句,以确保在备份发生之前将缓存在内存中的所有更改刷新到磁盘。

.DATA DIRECTORY子句是一种支持替代符号链接的方法,符号链接一直存在问题,从来没有被支持用于单独的InnoDB表。

MySQL 修改InnoDB重做日志文件的数量或大小

修改InnoDB重做日志文件的数量或大小
修改你的InnoDB重做日志文件的数量或大小,请执行以下步骤:
1.停止MySQL服务器,并确保它没有错误地关闭

mysql> show variables like 'innodb_log_file%';
+---------------------------+----------+
| Variable_name             | Value    |
+---------------------------+----------+
| innodb_log_file_size      | 50331648 |
| innodb_log_files_in_group | 2        |
+---------------------------+----------+
2 rows in set (0.00 sec)


[root@localhost ~]# service mysqld stop
Shutting down MySQL.... SUCCESS!

2.编辑my.cnf以更改日志文件配置。如果需要修改日志文件大小,请配置innodb_log_file_size。要增加日志文件的数量,可以配置

innodb_log_files_in_group。

[mysql@localhost mysql]$ vi my.cnf
....
innodb_log_file_size=100m
innodb_log_files_in_group=3

3.重新启动MySQL服务器
如果InnoDB检测到innodb_log_file_size大小与重做日志文件大小不同,它会写一个日志检查点,关闭并删除旧的日志文件,创建新的大小的志文件,并打开新的日志文件。

[root@localhost ~]# service mysqld start
Starting MySQL.................................. SUCCESS!


日志文件显示如下:

[mysql@localhost mysql]$ tail -f mysql.err
2022-03-02T02:44:15.775252Z 0 [Warning] Insecure configuration for --secure-file-priv: Current value does not restrict location of generated files. Consider setting it to a valid, non-empty path.
2022-03-02T02:44:15.775476Z 0 [Note] /mysqlsoft/mysql/bin/mysqld (mysqld 5.7.26-log) starting as process 613 ...
2022-03-02T02:44:15.787224Z 0 [Note] InnoDB: PUNCH HOLE support available
2022-03-02T02:44:15.787311Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2022-03-02T02:44:15.787376Z 0 [Note] InnoDB: Uses event mutexes
2022-03-02T02:44:15.787395Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2022-03-02T02:44:15.787411Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2022-03-02T02:44:15.788175Z 0 [Note] InnoDB: Number of pools: 1
2022-03-02T02:44:15.788515Z 0 [Note] InnoDB: Using CPU crc32 instructions
2022-03-02T02:44:15.793577Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2022-03-02T02:44:15.812360Z 0 [Note] InnoDB: Completed initialization of buffer pool
2022-03-02T02:44:15.817437Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2022-03-02T02:44:15.862640Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2022-03-02T02:44:16.043532Z 0 [Warning] InnoDB: Resizing redo log from 2*3072 to 3*6400 pages, LSN=2494312
2022-03-02T02:44:16.169341Z 0 [Warning] InnoDB: Starting to delete and rewrite log files.
2022-03-02T02:44:16.200462Z 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 100 MB
2022-03-02T02:44:16.200745Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:26.280622Z 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 100 MB
2022-03-02T02:44:26.281005Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:37.028157Z 0 [Note] InnoDB: Setting log file ./ib_logfile2 size to 100 MB
2022-03-02T02:44:37.029053Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:47.532468Z 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2022-03-02T02:44:47.532675Z 0 [Warning] InnoDB: New log files created, LSN=2494312
2022-03-02T02:44:47.533502Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2022-03-02T02:44:47.533760Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2022-03-02T02:44:48.119249Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2022-03-02T02:44:48.121693Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2022-03-02T02:44:48.121740Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2022-03-02T02:44:48.122598Z 0 [Note] InnoDB: Waiting for purge to start
2022-03-02T02:44:48.172771Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 32356ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)
2022-03-02T02:44:48.186082Z 0 [Note] InnoDB: 5.7.26 started; log sequence number 2494303
2022-03-02T02:44:48.186431Z 0 [Note] InnoDB: Loading buffer pool(s) from /mysqldata/mysql/ib_buffer_pool
2022-03-02T02:44:48.186776Z 0 [Note] Plugin 'FEDERATED' is disabled.
2022-03-02T02:44:48.366419Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2022-03-02T02:44:48.367248Z 0 [Warning] CA certificate ca.pem is self signed.
2022-03-02T02:44:48.369110Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
2022-03-02T02:44:48.371083Z 0 [Note] IPv6 is available.
2022-03-02T02:44:48.371145Z 0 [Note]   - '::' resolves to '::';
2022-03-02T02:44:48.371213Z 0 [Note] Server socket created on IP: '::'.
2022-03-02T02:44:48.430720Z 0 [Note] InnoDB: Buffer pool(s) load completed at 220302 10:44:48
2022-03-02T02:44:48.434777Z 0 [Note] Failed to start slave threads for channel ''
2022-03-02T02:44:48.452218Z 0 [Note] Event Scheduler: Loaded 0 events
2022-03-02T02:44:48.452566Z 0 [Note] /mysqlsoft/mysql/bin/mysqld: ready for connections.
Version: '5.7.26-log'  socket: '/mysqlsoft/mysql/mysql.sock'  port: 3306  Source distribution

其中以下部分显示了服务器重置日志文件的大小与数量

2022-03-02T02:44:16.043532Z 0 [Warning] InnoDB: Resizing redo log from 2*3072 to 3*6400 pages, LSN=2494312
2022-03-02T02:44:16.169341Z 0 [Warning] InnoDB: Starting to delete and rewrite log files.
2022-03-02T02:44:16.200462Z 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 100 MB
2022-03-02T02:44:16.200745Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:26.280622Z 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 100 MB
2022-03-02T02:44:26.281005Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:37.028157Z 0 [Note] InnoDB: Setting log file ./ib_logfile2 size to 100 MB
2022-03-02T02:44:37.029053Z 0 [Note] InnoDB: Progress in MB:
 100
2022-03-02T02:44:47.532468Z 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2022-03-02T02:44:47.532675Z 0 [Warning] InnoDB: New log files created, LSN=2494312


[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_log_file%';
+---------------------------+-----------+
| Variable_name             | Value     |
+---------------------------+-----------+
| innodb_log_file_size      | 104857600 |
| innodb_log_files_in_group | 3         |
+---------------------------+-----------+
2 rows in set (0.01 sec)

MySQL 减少InnoDB系统表空间的大小

减少InnoDB系统表空间的大小
不能从系统表空间中删除数据文件。若要减少系统表空间大小,请使用此过程:
1.使用mysqldump将所有的包括MySQL数据库中的InnoDB表dump出来,在5.6当前版本中,包括5张InnoDB表:

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------------------+
| Variable_name         | Value                              |
+-----------------------+------------------------------------+
| innodb_data_file_path | ibdata1:76M;ibdata2:50M:autoextend |
| innodb_data_home_dir  |                                    |
+-----------------------+------------------------------------+
2 rows in set (0.01 sec)

mysql> SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' and ENGINE='InnoDB';
+---------------------------+
| TABLE_NAME                |
+---------------------------+
| engine_cost               |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| plugin                    |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
+---------------------------+
19 rows in set (0.00 sec)



[mysql@localhost ~]$ mysqldump  -uroot -pxxzx7817600 --all-databases > all_db_dump_20220223.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

2.停止MySQL服务器

[mysql@localhost ~]$ mysqladmin -uroot -pxxzx7817600 shutdown
mysqladmin: [Warning] Using a password on the command line interface can be insecure.

3.删除所有已经存在的表空间文件(*.ibd),包括ibdata和ib_log文件。不要忘记删除MySQL数据库中的*.ibd文件。

[mysql@localhost mysql]$ find ./mysql -name "*.ibd"
./mysql/plugin.ibd
./mysql/servers.ibd
./mysql/help_topic.ibd
./mysql/help_category.ibd
./mysql/help_relation.ibd
./mysql/help_keyword.ibd
./mysql/time_zone_name.ibd
./mysql/time_zone.ibd
./mysql/time_zone_transition.ibd
./mysql/time_zone_transition_type.ibd
./mysql/time_zone_leap_second.ibd
./mysql/innodb_table_stats.ibd
./mysql/innodb_index_stats.ibd
./mysql/slave_relay_log_info.ibd
./mysql/slave_master_info.ibd
./mysql/slave_worker_info.ibd
./mysql/gtid_executed.ibd
./mysql/server_cost.ibd
./mysql/engine_cost.ibd
[mysql@localhost mysql]$ find ./mysql -name "*.ibd"    | xargs -n 1 rm -f

[mysql@localhost mysql]$ rm -rf ibdata*
[mysql@localhost mysql]$ rm -rf ib_log*
[mysql@localhost mysql]$ ls -lrt ibdata*
ls: 无法访问ibdata*: 没有那个文件或目录
[mysql@localhost mysql]$ ls -lrt ib_log*
ls: 无法访问ib_log*: 没有那个文件或目录

4.删除InnoDB表的.frm文件

[mysql@localhost mysql]$ rm -rf mysql/plugin..frm
[mysql@localhost mysql]$ rm -rf mysql/servers..frm
[mysql@localhost mysql]$ rm -rf mysql/help_topic..frm
[mysql@localhost mysql]$ rm -rf mysql/help_category..frm
[mysql@localhost mysql]$ rm -rf mysql/help_relation.frm
[mysql@localhost mysql]$ rm -rf mysql/help_keyword.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_name.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_transition.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_transition_type.frm
[mysql@localhost mysql]$ rm -rf mysql/time_zone_leap_second.frm
[mysql@localhost mysql]$ rm -rf mysql/innodb_table_stats.frm
[mysql@localhost mysql]$ rm -rf mysql/innodb_index_stats.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_relay_log_info.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_master_info.frm
[mysql@localhost mysql]$ rm -rf mysql/slave_worker_info.frm
[mysql@localhost mysql]$ rm -rf mysql/gtid_executed.frm
[mysql@localhost mysql]$ rm -rf mysql/server_cost.frm
[mysql@localhost mysql]$ rm -rf mysql/engine_cost.frm

5.配置一个新表空间

[mysql@localhost mysql]$ vi my.cnf
.......
innodb_data_file_path = ibdata1:10M:autoextend

6.重启MySQL服务器

[root@localhost ~]# service mysqld start
Starting MySQL......... SUCCESS!

7.导入dump文件

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 < all_db_dump_20220223.sql
mysql: [Warning] Using a password on the command line interface can be insecure.

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+
2 rows in set (0.01 sec)

InnoDB系统表空间的文件变回原来的ibdata1了

mysql> SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql' and ENGINE='InnoDB';
+---------------------------+
| TABLE_NAME                |
+---------------------------+
| engine_cost               |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| plugin                    |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
+---------------------------+
19 rows in set (0.01 sec)

注意:如果您的数据库只使用InnoDB引擎,那么可能更简单的方法是转储所有数据库,停止服务器,删除所有数据库和InnoDB日志文件,重新启动服务器,并导入转储文件。

MySQL 增加InnoDB系统表空间大小

增加InnoDB系统表空间大小
增加InnoDB系统表空间大小的最简单的方法是从一开始就配置为自动扩展。在表空间定义中为最后一个数据文件指定autoextend属性。当InnoDB用完空间时,会自动增加64MB的文件大小。可以通过设置innodb_autoextend_increment系统变量的值来更改增量大小,该变量以兆字节为单位度量。

mysql> show variables like 'innodb_autoextend_increment';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_autoextend_increment | 64    |
+-----------------------------+-------+
1 row in set (0.01 sec)

通过添加另一个数据文件,可以按定义的数量扩展系统表空间:
1.关闭MySQL服务器

2.如果上一个数据文件是用autoextend关键字定义的,那么根据它实际增长的大小,将其定义更改为使用固定大小。检查数据文件的大小,将其四舍四入到最接近的1024*1024字节(= 1MB)的倍数,并在innodb_data_file_path中显式指定这个四舍五入的大小。

3.在innodb_data_file_path的末尾添加一个新的数据文件,可以选择使该文件自动扩展。只有innodb_data_file_path中的最后一个数据文件可以被指定为自动扩展。

4.重新启动MySQL服务器。

例如,这个表空间只有一个自动扩展的数据文件ibdata1

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+
2 rows in set (0.00 sec)

假设这个数据文件随着时间的推移增长到76MB。下面是修改原始数据文件以使用固定大小并添加新的自动扩展数据文件后的配置行

innodb_data_home_dir =
innodb_data_file_path =  ibdata1:76M;ibdata2:50M:autoextend

当您向系统表空间配置添加一个新的数据文件时,请确保文件名没有引用现有的文件。当您重启服务器时,InnoDB会创建并初始化该文件

a.关闭MySQL服务器

[root@localhost ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!

b.检查数据文件的大小

[mysql@localhost mysql]$ du -sh ibdata1
76M     ibdata1

c.在innodb_data_file_path的末尾添加一个新的数据文件,可以选择使该文件自动扩展。

innodb_data_file_path =  ibdata1:76M;ibdata2:50M:autoextend

d.重启MySQL服务器

[root@localhost ~]# service mysqld start
Starting MySQL..... SUCCESS!

[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'innodb_data%';
+-----------------------+------------------------------------+
| Variable_name         | Value                              |
+-----------------------+------------------------------------+
| innodb_data_file_path | ibdata1:76M;ibdata2:50M:autoextend |
| innodb_data_home_dir  |                                    |
+-----------------------+------------------------------------+
2 rows in set (0.01 sec)

[root@localhost mysql]# ls -lrt ibdata*
-rw-r-----. 1 mysql mysql 52428800 2月  23 11:13 ibdata2
-rwxr-xr-x. 1 mysql mysql 79691776 2月  23 11:13 ibdata1

MySQL 配置索引页的合并阈值

配置索引页的合并阈值
您可以为索引页配置MERGE_THRESHOLD值。如果一个索引页的“page-full”百分比低于MERGE_THRESHOLD值,当一个行被删除或当一个行被UPDATE 操作缩短时,InnoDB会尝试合并这个索引页和相邻的索引页。默认的MERGE_THRESHOLD值是50,这是以前的硬编码值。MERGE_THRESHOLD最小值为1,最大值为50。

当索引页的页满百分比低于50%(默认的MERGE_THRESHOLD设置)时,InnoDB会尝试将索引页与相邻页合并。如果两个页面都接近50%的满,那么在页面合并后不久就会发生页面分割。如果频繁发生这种合并-分割行为,则会对性能产生不利影响。为了避免频繁的合并分割,你可以降低MERGE_THRESHOLD值,这样InnoDB尝试页面合并的百分比就会降低。以较低的页满百分比合并页面会在索引页中留下更多的空间,并有助于减少合并-分割行为。

可以为一个表或单个索引定义索引页的MERGE_THRESHOLD。为单个索引定义的MERGE_THRESHOLD值优先于为表定义的MERGE_THRESHOLD值。如果未定义,MERGE_THRESHOLD值默认为50。

设置表的MERGE_THRESHOLD
可以使用CREATE TABLE语句的table_option COMMENT子句为一个表设置MERGE_THRESHOLD值。例如:

CREATE TABLE t1 (
id INT,
KEY id_index (id)
) COMMENT='MERGE_THRESHOLD=45';

还可以使用ALTER TABLE的table_option COMMENT子句为现有表设置MERGE_THRESHOLD值

CREATE TABLE t1 (
id INT,
KEY id_index (id)
);

ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';

为单个索引设置MERGE_THRESHOLD
要为单个索引设置MERGE_THRESHOLD值,可以使用带有CREATE TABLE、ALTER TABLE或CREATE INDEX的index_option COMMENT子句,如下面的示例所示:
.使用CREATE TABLE为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (
    -> id INT,
    -> KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40'
    -> );
Query OK, 0 rows affected (0.11 sec)

.使用ALTER TABLE为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (
    -> id INT,
    -> KEY id_index (id)
    -> );
ALTER TABLE t1 DROP KEY id_index;
ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';Query OK, 0 rows affected (0.17 sec)

mysql> ALTER TABLE t1 DROP KEY id_index;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

使用CREATE INDEX为单个索引设置MERGE_THRESHOLD:

mysql> CREATE TABLE t1 (id INT);
Query OK, 0 rows affected (0.14 sec)

mysql> CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

不能在索引级别修改GEN_CLUST_INDEX的MERGE_THRESHOLD值,GEN_CLUST_INDEX是InnoDB在创建InnoDB表时,在没有主键或唯一键索引的情况下创建的聚集索引。只能通过设置表的MERGE_THRESHOLD来修改GEN_CLUST_INDEX的MERGE_THRESHOLD值

查询索引的MERGE_THRESHOLD值
当前索引的MERGE_THRESHOLD值可以通过查询INNODB_SYS_INDEXES表获得。例如:

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME='id_index' \G
*************************** 1. row ***************************
       INDEX_ID: 265
           NAME: id_index
       TABLE_ID: 267
           TYPE: 0
       N_FIELDS: 1
        PAGE_NO: 4
          SPACE: 269
MERGE_THRESHOLD: 40
1 row in set (0.00 sec)

如果使用table_option COMMENT子句显式定义,可以使用SHOW CREATE TABLE查看表的MERGE_THRESHOLD值

mysql> SHOW CREATE TABLE t1 \G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  KEY `id_index` (`id`) COMMENT 'MERGE_THRESHOLD=40'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

在索引级别定义的MERGE_THRESHOLD值优先于为表定义的MERGE_THRESHOLD值。如果未定义,MERGE_THRESHOLD默认为50% (MERGE_THRESHOLD=50,这是以前的硬编码值。

同样,如果使用index_option COMMENT子句显式地定义,也可以使用SHOW INDEX查看索引的MERGE_THRESHOLD值:

mysql> show index from t1 \G
*************************** 1. row ***************************
        Table: t1
   Non_unique: 1
     Key_name: id_index
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment: MERGE_THRESHOLD=40
1 row in set (0.00 sec)

测量MERGE_THRESHOLD设置的效果:

INNODB_METRICS表提供了两个计数器,可以用来衡量MERGE_THRESHOLD设置对索引页合并的影响。

mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME like '%index_page_merge%';
+-----------------------------+----------------------------------------+
| NAME                        | COMMENT                                |
+-----------------------------+----------------------------------------+
| index_page_merge_attempts   | Number of index page merge attempts    |
| index_page_merge_successful | Number of successful index page merges |
+-----------------------------+----------------------------------------+
2 rows in set (0.00 sec)

当降低MERGE_THRESHOLD值时,目标是:
.页面合并尝试和成功合并的次数更少
.尝试合并和成功合并页面的次数相同

太小的MERGE_THRESHOLD设置由于大量的空页面空间导致大量的数据文件。

MySQL 配置InnoDB配置非持久优化器统计信息参数

配置非持久优化器统计信息参数
本节介绍如何配置非持久优化器统计信息。当innodb_stats_persistent=OFF或使用STATS_PERSISTENT=0创建或修改单个表时,优化器统计信息不会被持久化到磁盘。相反,统计信息存储在内存中,并且在服务器关闭时丢失。统计数据还由某些操作在某些条件下定期更新。

从MySQL 5.6.6开始,默认情况下,优化器统计数据被持久化到磁盘上,由innodb_stats_persistent配置选项启用。

优化器数据更新
在以下情况出现时非持久化的优化器统计信息会被更新:
.执行analyze table

.运行show table status,show index,或者在innodb_stats_on_metadata选项被启用时查询information_schema.tables或information_schema.statistics表。

MySQL 5.6.6中,当持久化优化器统计信息被启用时,innodb_stats_on_metadata默认设置为OFF。启用innodb_stats_on_metadata可能会降低具有大量表或索引的模式的访问速度,并降低涉及InnoDB表的查询的执行计划的稳定性。innodb_stats_on_metadata使用SET语句全局配置。set global innodb_stats_on_metadata=ON

innodb_stats_on_metadata只适用于优化器统计信息配置为非持久化(当innodb_stats_persistent被禁用时)。

.启动mysql客户端时启用–auto-rehash选项,这是默认设置。auto-rehash选项会打开所有InnoDB表,打开表的操作会导致统计数据重新计算。为了提高mysql客户端的启动和更新统计信息时间,你可以使用–disable-auto-rehash选项关闭auto-rehash。自动auto-rehash特性允许交互用户自动完成数据库、表和列名的命名。

.表第一次打开。

.InnoDB检测到有1 / 16的表在上次统计数据更新后被修改。

配置采样页面数
MySQL查询优化器使用关于键分布的估计统计信息,根据索引的相对选择性为执行计划选择索引。当InnoDB更新优化器统计数据时,它会从表上的每个索引中随机取样,以估计索引的基数。(这种技术被称为随机潜水。)

为了控制统计信息评估的质量(从而为查询优化器提供更好的信息),可以使用参数innodb_stats_transient_sample_pages更改抽样页面的数量。默认的抽样页面数是8,这可能不足以产生准确的评估,导致查询优化器的索引选择很差。这种技术对于大型表和连接中使用的表尤其重要。对这样的表进行不必要的全表扫描可能会造成严重的性能问题。

当innodb_stats_transient_sample_pages =0时,innodb_stats_persistent的值会影响所有InnoDB表和索引的索引采样。当您更改索引样本大小时,请注意以下潜在的重大影响。
.小值像1或2可以导致不精确的基数评估

.增加innodb_stats_transient_sample_pages的值可能需要更多的磁盘读取。大于8(比如100)的值会导致打开表或执行SHOW table STATUS所需的时间显著放缓。

.优化器可能会根据索引选择性的不同估计选择非常不同的查询计划

无论innodb_stats_transient_sample_pages的值是什么,设置该选项并保持该值。选择一个值,它可以为数据库中的所有表提供合理准确的估计,而不需要过多的I/O。因为除了在执行ANALYZE TABLE时,统计数据会在其他时间自动重新计算,所以增加索引样本大小,运行ANALYZE TABLE,然后再次减少样本大小是没有意义的。

较小的表通常比较大的表需要更少的索引样本。如果你的数据库有很多大的表,考虑使用一个更大的innodb_stats_transient_sample_pages值。

评估InnoDB表analyze table的复杂度
InnoDB表的ANALYZE TABLE复杂度依赖于:
.采样的页面数,由innodb_stats_persistent_sample_pages定义

.表中索引列的数目

.分区数。如果表没有分区,则认为分区数为1。

使用这些参数,估计ANALYZE TABLE复杂度的近似公式是
innodb_stats_persistent_sample_pages的值*表中索引的列数*分区数

通常,结果值越大,ANALYZE TABLE的执行时间就越长

innodb_stats_persistent_sample_pages定义了在全局级别上采样的页面数量。要设置单个表的采样页数,请使用有STATS_SAMPLE_PAGES选项的CREATE TABLE或ALTER TABLE的语句。

如果innodb_stats_persistent=OFF,则由innodb_stats_transient_sample_pages定义采样的页面数

要了解估算ANALYZE TABLE复杂度的更深入的方法,请考虑以下示例:
在大O符号中,ANALYZE TABLE的复杂度被描述为:

O(n_sample
* (n_cols_in_uniq_i
+ n_cols_in_non_uniq_i
+ n_cols_in_pk * (1 + n_non_uniq_i))
* n_part)

.n_sample是采样的页面数(由innodb_stats_persistent_sample_pages定义)

.n_cols_in_uniq_i是所有唯一索引中所有列的总数(不计算主键列)

.n_cols_in_non_uniq_i是所有非唯一索引中所有列的总数

.n_cols_in_pk是主键中的列数(如果没有定义主键,InnoDB会在内部创建一个单列主键)

.n_non_uniq_i是表中非唯一索引的个数

.n_part是分区的数量。如果没有定义分区,则将表视为单个分区。

现在,考虑下面的表(表t),它有一个主键(2列)、一个唯一索引(2列)和两个非唯一索引(各有两列):

mysql> CREATE TABLE t (
    -> a INT,
    -> b INT,
    -> c INT,
    -> d INT,
    -> e INT,
    -> f INT,
    -> g INT,
    -> h INT,
    -> PRIMARY KEY (a, b),
    -> UNIQUE KEY i1uniq (c, d),
    -> KEY i2nonuniq (e, f),
    -> KEY i3nonuniq (g, h)
    -> );
Query OK, 0 rows affected (0.13 sec)

对于上述算法所需的列和索引数据,查询mysql.innodb_index_stats来查看表t的持久索引统计信息。n_diff_pfx%显示了每个索引列的统计信息。
例如,列a和列b用于计算主键索引。对于非唯一索引,除了用户定义的列外,还要统计主键列(a,b)。

mysql> select index_name, stat_name, stat_description
    -> from mysql.innodb_index_stats
    -> where
    -> database_name='mysql' and
    -> table_name='t' and
    -> stat_name like 'n_diff_pfx%';
+------------+--------------+------------------+
| index_name | stat_name    | stat_description |
+------------+--------------+------------------+
| PRIMARY    | n_diff_pfx01 | a                |
| PRIMARY    | n_diff_pfx02 | a,b              |
| i1uniq     | n_diff_pfx01 | c                |
| i1uniq     | n_diff_pfx02 | c,d              |
| i2nonuniq  | n_diff_pfx01 | e                |
| i2nonuniq  | n_diff_pfx02 | e,f              |
| i2nonuniq  | n_diff_pfx03 | e,f,a            |
| i2nonuniq  | n_diff_pfx04 | e,f,a,b          |
| i3nonuniq  | n_diff_pfx01 | g                |
| i3nonuniq  | n_diff_pfx02 | g,h              |
| i3nonuniq  | n_diff_pfx03 | g,h,a            |
| i3nonuniq  | n_diff_pfx04 | g,h,a,b          |
+------------+--------------+------------------+
12 rows in set (0.01 sec)

根据上面显示的索引统计数据和表定义,可以确定以下值:
.n_cols_in_uniq_i,不计算主键列的所有唯一索引中所有列的总数为2 (c和d)

.n_cols_in_non_uniq_i,所有非唯一索引中所有列的总数,为4 (e、f、g和h)

.n_cols_in_pk,主键中的列数是2(a和b)

.n_non_uniq_i,表中非唯一索引的数量为2 (i2nonuniq和i3nonuniq))

.n_part, 分区数,为1

现在可以计算innodb_stats_persistent_sample_pages *(2 + 4 + 2 *(1 + 2)) * 1来确定扫描的叶页数。如果将innodb_stats_persistent_sample_pages设置为默认值20,并将默认的页面大小设置为16 KiB (innodb_page_size=16384),那么你可以估计为表t读取20 * 12 * 16384字节,或者大约4 MiB。

所有4MiB可能不是从磁盘读取的,因为一些叶页可能已经缓存在缓冲池中。

基于mysqld_multi实现MySQL 5.7.24多实例多进程配置

MySQL多实例的原理

mysql多实例,简单理解就是在一台服务器上,mysql服务开启多个不同的端口(如3306、3307、3308)运行多个服务进程。这些 mysql 服务进程通过不同的 socket来监听不同的数据端口,进而互不干涉的提供各自的服务。

在同一台服务器上,mysql 多实例会去共用一套 mysql 应用程序,因此你在部署 mysql 的时候只需要部署一次mysql程序即可,无需多次部署。但是,mysql多实例之间会各自使用不同的 my.cnf配置文件、启动程序和数据文件。在提供服务方面,mysql多实例在逻辑上看起来是各自独立,互不干涉的,并且多个实例之间是根据配置文件的设定值,来获取相关服务器的硬件资源。

优点如下:

有效利用服务器资源
当单个服务器资源过剩时,可以充分利用剩余的资源来提供更多的服务
节约服务器资源
当公司资金紧张,但数据库又需要数据库之间各自提供服务时,并且还想使用主从同步等技术,此时多实例就再好不过了
方便后期架构扩展
当公司的某个项目才启动时,启动初期并不一定有很大的用户量,因此可以先用一组物理数据库服务器,在上面部署多个实例,方便后续架构扩展、迁移

缺点如下:
资源互相抢占问题
当某个服务实例并发很高或者有慢查询时,整个实例会消耗更多的内存、CPU和IO资源,这将导致服务器上的其它实例提供服务的质量下降
mysql 多实例在生产环境下的应用场景!

当一个公司业务访问量不太大,又想节俭成本,并且还希望不同业务的数据库服务能够各自尽量独立,提供服务能够互相不受影响。另外还需要应用主从同步等技术来提供数据库备份或读写分离服务,以及方便后期业务量增大时,数据库架构的扩展和迁移。此时,Mysql 多实例就再好不过了。比如,我们可以通过在 3 台服务器部署 6-9 个实例,然后交叉做主从同步备份及读写分离,来实现 6-9 台服务器才能够达到的效果

公司业务访问量不是太大的时候,服务器的资源基本都是过剩状态。此时就很适合 mysql 多实例的应用。如果对 SQL语句优化做的比较好,mysql 多实例是一个很值得去使用的技术。即使后期业务并发很大,只要合理分配好系统资源,也不会有太大的问题

为了规避 mysql 对 SMP 架构不支持的缺陷,我们可以使用 mysql 多实例绑定处理器的办法(NUMA处理器必须支持,不过现在大部分处理器都支持的)将不同的数据库分配到不同的实例上提供数据服务;

传统游戏行业的 MMO/MMORPG以及Web Game,会将每个服都对应一个数据库,而且可能经常要做很多数据查询和数据订正工作。此时,为了减少维护而出错的概率,我们也可以采用多实例的部署方式,按区的概念来分配数据库。

Mysql多实例实现的3种方式

1、基于多配置文件

通过使用多个配置文件来启动不同的进程,以此来实现多实例。

优点:逻辑简单,配置简单

缺点:管理起来不方便

2、基于mysqld_multi
通过官方自带的 mysqld_multi 工具,使用单独配置文件来实现多实例

优点: 便于集中管理管理

缺点: 不方便针对每个实例配置进行定制

3、基于IM
使用 MySQL 实例管理器(MYSQLMANAGER),这个方法好像比较好不过也有点复杂

优点:便于集中管理

缺点:耦合度高。IM一挂,实例全挂/
不方便针对每个实例配置进行定制

MySQL本身就可以通过多实例方式运行,只要修改启动脚本和配置文件,把端口、basedir、datadir 文件夹分开后,多个实例的运行就会互不影响。但是这种方式操作起来太过繁杂,所以MySQL官方提供了一个mysqld_multi 的程序来辅助实现多实例操作。

一、创建并初始化数据目录
几个实例要分开运行,必然要把数据库文件放到不同目录中,所以第一步是要建立各个实例的数据目录,这里假设我们要运行三个实例,端口分别是3306,3307,3308,为了方便维护,我们把数据文件夹也按照端口号来命名:

[root@localhost ~]# mkdir -p /data/mysql/{3306,3307,3308}
[root@localhost ~]# chown mysql:mysql /data/mysql/{3306,3307,3308}
[root@localhost ~]# ls -ld /data/mysql/{3306,3307,3308}
drwxr-xr-x 2 mysql mysql 6 12月  7 16:37 /data/mysql/3306
drwxr-xr-x 2 mysql mysql 6 12月  7 16:37 /data/mysql/3307
drwxr-xr-x 2 mysql mysql 6 12月  7 16:37 /data/mysql/3308

通过配置文件指定并初始化数据目录

[root@localhost ~]# cp /etc/my.cnf /data/mysql/3308.cnf
[root@localhost ~]# vim /data/mysql/3308.cnf
[mysqld]
port=3308
datadir=/data/mysql/3308/
socket=/tmp/mysql3308.sock
symbolic-links=0

[mysqld_safe]
log-error=/data/mysql/3308.log
pid-file=/usr/local/mysql/data/3308.pid

[client]
port=3308
socket=/tmp/mysql3308.sock

[root@localhost ~]# mysqld --defaults-file=/data/mysql/3308.cnf --initialize-insecure --user=mysql

初始化完成之后,后续的配置不需要3308.cnf文件,实例的参数会在my.cnf中集中配置。注意,data目录在初始化前,必须为空,不然初始化是会报错

重复上面两个步骤,把3307、3306目录初始化好。

[root@localhost ~]# cat /data/mysql/3306.cnf
[mysqld]
port=3306
datadir=/data/mysql/3306/
socket=/tmp/mysql3306.sock
symbolic-links=0

[mysqld_safe]
log-error=/data/mysql/3306.log
pid-file=/usr/local/mysql/data/3306.pid

[client]
port=3306
socket=/tmp/mysql3306.sock
[root@localhost ~]# cat /data/mysql/3307.cnf
[mysqld]
port=3307
datadir=/data/mysql/3307/
socket=/tmp/mysql3307.sock
symbolic-links=0

[mysqld_safe]
log-error=/data/mysql/3307.log
pid-file=/usr/local/mysql/data/3307.pid

[client]
port=3307
socket=/tmp/mysql3307.sock
[root@localhost ~]# mysqld --defaults-file=/data/mysql/3307.cnf --initialize-insecure --user=mysql
[root@localhost ~]# mysqld --defaults-file=/data/mysql/3306.cnf --initialize-insecure --user=mysql

二、配置my.cnf文件集中管理多个实例

[root@localhost ~]# cp /etc/my.cnf /etc/my.cnf.bak
[root@localhost ~]# vim /etc/my.cnf
[mysqld_multi]
mysqld=/usr/local/mysql/bin/mysqld_safe
mysqladmin=/usr/local/mysql/bin/mysqladmin

[mysqld1]
port=3306
socket=/tmp/mysql3306.sock
datadir=/data/mysql/3306/
skip-external-locking
log-bin=/data/mysql/3306/mysql-bin
server-id=3306
user=mysql

[mysqld2]
port=3307
socket=/tmp/mysql3307.sock
datadir=/data/mysql/3307/
skip-external-locking
log-bin=/data/mysql/3307/mysql-bin
server-id=3307
user=mysql

[mysqld3]
port=3308
socket=/tmp/mysql3308.sock
datadir=/data/mysql/3308/
skip-external-locking
log-bin=/data/mysql/3308/mysql-bin
server-id=3308
user=mysql

[mysql]
no-auto-rehash

mysqld_multi的配置文件和一般MySQL配置不同,没有[mysqld]段,取而代之的是[mysqld1]、[mysqld2]等配置段,每个配置段代表一个MySQL实例。

三、管理多个MySQL实例
1,启动多个MySQL实例
启动多个实例时需要一个启动脚本,这个脚本一般在/usr/local/mysql/support-files目录下的mysqld_multi.server文件

[root@localhost ~]# cp /usr/local/mysql/support-files/mysqld_multi.server /etc/init.d/mysqld_multi

启动多个MySQL实例

[root@localhost ~]# /etc/init.d/mysqld_multi start 1-3

启动三个MySQL实例,注意这里的数字和my.cnf中的[mysqldN]对应,1-3就是启动[mysqld1]、[mysqld2]、[mysqld3]配置段的MySQL实例。

[root@localhost ~]# netstat -lnpt | grep -E "3306|3307|3308"
tcp6       0      0 :::3306                 :::*                    LISTEN      2744/mysqld
tcp6       0      0 :::3307                 :::*                    LISTEN      65502/mysqld
tcp6       0      0 :::3308                 :::*                    LISTEN      65499/mysqld

查看端口,看MySQL有没有正常启动,如果没有启动或报错,一般报错详细日志存在各个实例data目录下的主机名.err文件中,打开此文件查找错误原因,逐步排错就可以了。

2,关闭多个MySQL实例

[root@localhost ~]# /etc/init.d/mysqld_multi stop 1-3
[root@localhost ~]# netstat -lnpt | grep -E "3306|3307|3308"

也可以使用以下命令:

killall -u mysql 或者 kill -9 the-mysql-pid

四、root账户管理
前面初始化数据库时用的是–initialize-insecure参数,所以我们初始化的数据库,root账户是没有密码的,要先改密码为123456:

mysqladmin -uroot password '123456' -S /tmp/mysql3306.sock
mysqladmin -uroot password '123456' -S /tmp/mysql3307.sock
mysqladmin -uroot password '123456' -S /tmp/mysql3308.sock

或者:

mysqladmin -uroot password '123456' -P3306 -h127.0.0.1
mysqladmin -uroot password '123456' -P3307 -h127.0.0.1
mysqladmin -uroot password '123456' -P3308 -h127.0.0.1

五、连接mysql多实例:

[root@localhost ~]# mysql -u root -p123456 -S /tmp/mysql3306.sock
[root@localhost ~]# mysql -u root -p123456 -S /tmp/mysql3307.sock
[root@localhost ~]# mysql -u root -p123456 -S /tmp/mysql3308.sock

mysqldump 数据库备份程序

mysqldump 数据库备份程序
mysqldump客户端工具执行逻辑备份,生成一组SQL语句可以用来执行重新创建原数据库对象定义和表数据。它dumps一个或多个MySQL数据库的备份或者传输到另外的服务器。mysqldump命令也可以生成CSV或,其它文本或XML格式的输出

mysqldump的优点是在还原之前它可以方便与灵活的查看或者编辑输出。可以克隆数据库来给开发人员和DBA使用,或者提供测试环境。它并不是一种用来备份大量数据的快速或可扩展的方案。使用大数据大小,即使备份操作花费的时间合理,但还原数据可能非常缓慢因为重放SQL语句调用磁盘I/O来执行插入操作,索引创建等等。

对于大规模的备份和还原,物理备份更合适,可以以它们的原有格式来复制数据文件来快速完成还原操作:
.如果你的表主要是InnoDB表,或者如果你有一种混合的InnoDB与MyISAM表,可以考虑MySQL企业级备份产品的mysqlbackup命令。它为InnoDB备份提供了最好的性能并且破坏性最小,它也可以从MyISAM和其它存储引擎中备份数据表,并且它提供了许多不同的选项来适应不同的备份场景。

mysqldump可以逐行检索和dump表的内容或者它可以在dump它之前从一个表与内存的缓存中来检索整个内容。如果dump一个大表从内存中的缓存中检索可能是一个问题。为了逐行dump表,使用–quick选项(或–opt,它启用–quick)–opt选项(因此–quick)缺省被启用,因此启用内存缓存,使用–skip-quick选项.

如果使用一个最近版本的mysqldump来生成一个dump被加载到一个旧版本的MySQL服务器中,使用–skip-opt选项来代替–extended-insert选项。

有三种常用方式来使用mysqldump命令来完成对一个或多个表,一个或多个数据库,或整个MySQL服务器来进行dump:

shell> mysqldump [options] db_name [tbl_name ...]
shell> mysqldump [options] --databases db_name ...
shell> mysqldump [options] --all-databases

为了dump整个数据库,在db_name后面不要接任何表名,或者使用–database或–all-databases选项。

mysqldump支持以下选项,它可以在命令行或在选项文件中的[mysqldump]与[client]组中进行指定。

mysqldump选项:
–add-drop-database 在每个create database语句之前加上drop database语句

–add-drop-table 在每个create table语句之前加上drop table语句

–add-drop-trigger 在每个create trigger语句之前加上drop table语句

–add-locks 使用lock tables与unlock tables语句来包围每个表的dump

–all-databases dump所有数据库中的所有表

–allow-keywords 允许创建关键字列名

–apply-slave-statements 在change master语句之前包含stop slave,在结束输出之前包含start slave

–bind-address 使用特定的网络接口来连接MySQL服务器

–character-sets-dir 安装字符集的目录

–comments 添加注释到dump文件中

–compact 产生更紧凑的输出

–compatible 产生的输出将与其它的数据库系统或者旧版本的MySQL服务器更兼容

–complete-insert 使用完整的insert语句包括列名

–compress 对在客户端和服务器之间发送的所有信息进行压缩

–create-options 在create table语句中包含所有的MySQL特定的表选项

–databases 将所有的命名参数解释为数据库名

–debug 写调试日志

–debug-check 当程序退出时打印调试信息

–debug-info 当程序退出时打印调试信息,内存与CPU统计信息

–default-auth 要使用的身份认证插件

–default-character-set 指定的缺省字符集

–default-extra-file 除了常用的选项文件外还要读取的选项文件

–default-file 只读指定的选项文件

–default-group-suffix 选项组后缀值

–delete-master-logs 在一个主复制服务器上,在执行dump操作后删除binary日志文件

–disable-keys 对于每个表,围绕insert语句使用语句来禁用与启用关键字

–dump-date 如果–comments被指定,包含dump日期作为”Dump completed on”注释

–dump-slave 包含change master语句来列出slave’s master相关的二进制日志

–enable-cleartext-plugin 使用cleartext身份认证插件

–events 来自转储数据库的转储事件

–extended-insert 使用多行插入语法

–fields-enclosed-by 这个选项与–tab选项一起使用并且与load data infile相关子句有相同的意思

–fields-escaped-by 这个选项与–tab选项一起使用并且与load data infile相关子句有相同的意思

–fields-optionally-enclosed-by 这个选项与–tab选项一起使用并且与load data infile相关子句有相同的意思。

–fields-terminated-by 这个选项与–tab选项一起使用并且与load data infile相关子句有相同的意思

–flush-logs 在开始dump之前清空MySQL服务器的日志文件

–flush-privileges 在dump MySQL数据库后发布一个flush privileges语句。

–force 在一个表被dump时即使出现错误也会继续

–help 显示帮助信息并退出

–hex-blob 使用十六进制表示法来dump二进制列

–host 要连接的主机(IP地址或主机名)

–ignore-error 忽略特定的错误信息

–ignore-table 不dump指定的表

–include-master-host-port 在使用–dump-slave生成的change master语句中包含master_host/master_port选项

–insert-ignore 写insert ignore而不是insert语句

–lines-terminated-by 这个选项与–tab选项一起使用并且有与load data infile相关子句相同的意思

–lock-all-tables 跨所有数据库锁定所有表

–lock-tables 在dump他们之前锁定所有表

–log-error 将警告与错误追加到指定文件

–master-data 输出所写入的二进制日志文件名与位置

–max_allowed_packet 发送到到服务器或从服务器接收到的最大包长度

-net_buffer_length TCP/IP与socket通信的缓冲大小

–no-autocommit 对于每个dump表的insert语句包含了set autocommit=0与commit语句

–no-create-db 不写create database语句

–no-create-info 对于重建的每个dump表不写create table语句

–no-data 不dump表的内容

–no-defaults 不读取选项文件

–no-set-names 与–skip-set-charset相同

–no-tablespaces 在输出中不写入任何create logfile group或create tablespace语句

–opt 对于–add-drop-table –add-locks –create-options –disable-kyes –extended-insert –lock-tables –quick –sset-charset的速记法

–order-by-primary 通过主键或它的第一个唯一索引排序来dump每个表的行记录

–password 当连接服务器时使用的密码

–pipe 在Windows上,使用命名管道连接服务器

–plugin-dir 插件被安装的目录

–port 用于连接的TCP/IP端口号

–print-defaults 打印缺省选项

–protocol 使用的连接协议

–quick 从服务器中一次一行地检索数据

–quote-names 引号内的标识符

–replace 写replace语句而不是insert语句

–result-file 指示输出到指定文件

–routines 从被dump的数据库中dump存储程序(过程与函数)

–secure-auth 不使用旧格式发送密码到服务器

–set-charset 添加set names default_character_set到输出中

–set-gtid-purged 是否向输出添加set @@global.gtid_purged

–shared-memory-base-name 用于共享内存连接的共享内存名

–single-transaction 在从服务器dump数据之前执行begin sql语句

–skip-add-drop-table 在每个create table语句之前不添加drop table语句

–skip-add-locks 不添加锁

–skip-comments 不添加注释到dump文件

–skip-compact 不产生更多紧凑输出

–skip-disable-keys 不禁用关键字

–skip-extended-insert 关闭扩展插入

–skip-opt 关闭–opt选项集

–skip-quick 不从服务器一次一行地检索表的行

–skip-quote-names 不要引用标识符

–skip-set-charset 不写set names语句

–skip-triggers 不dump触发器

–skip-tz-utc 关闭tz-utc

–socket 对于本地连接,使用的Unix socket文件

–ssl 启用加密连接

–ssl-ca 包含可信SSL CA列表的文件路径

–ssl-capath 包含PEM格式可信SSL CA认证的目录路径

–ssl-cert 包含PEM格式X509认证的文件路径

–ssl-cipher 用于连接加密的允许密码列表

–ssl-crl 包含证书撤销列表的文件路径

–ssl-crlpath 包含证书撤销列表文件的目录的路径

–ssl-key 包含PEM格式的X509 钥匙的文件路径

–ssl-mode 连接服务器的安全状态

–ssl-verify-server-cert 根据连接到服务器时使用的主机名验证服务器证书公共名称值

–tab 生成用制表符分隔的数据文件

–tables 覆盖–database或-B选项

–tls-version 对于加密连接允许的连接协议

–triggers 对于每个被dump的表dump触发器

–tz-utc 添加set time_zone=’+00:00’到dump文件

–user 连接服务器时所使用的用户名

–verbose 详细模式

–version 显示版本信息并退出

–where 通过指定where条件只dump所选择的行

–xml 生成XML输出

1、备份命令
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –database 数据库名 > 文件名.sql

例如: mysqldump -h 192.168.1.100 -p 3306 -uroot -ppassword --database cmdb > /data/backup/cmdb.sql

2、备份压缩
导出的数据有可能比较大,不好备份到远程,这时候就需要进行压缩
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –database 数据库名 | gzip > 文件名.sql.gz

例如: mysqldump -h192.168.1.100 -p 3306 -uroot -ppassword --database cmdb | gzip > /data/backup/cmdb.sql.gz

3、备份同个库多个表
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –database 数据库名 表1 表2 …. > 文件名.sql

例如 mysqldump -h192.168.1.100 -p3306 -uroot -ppassword cmdb t1 t2 > /data/backup/cmdb_t1_t2.sql

4、同时备份多个库
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –databases 数据库名1 数据库名2 数据库名3 > 文件名.sql

例如:mysqldump -h192.168.1.100 -uroot -ppassword --databases cmdb bbs blog > /data/backup/mutil_db.sql

5、备份实例上所有的数据库
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –all-databases > 文件名.sql

例如:mysqldump -h192.168.1.100 -p3306 -uroot -ppassword --all-databases > /data/backup/all_db.sql

6、备份数据出带删除数据库或者表的sql备份
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –add-drop-table –add-drop-database 数据库名 > 文件名.sql

例如:mysqldump -uroot -ppassword --add-drop-table --add-drop-database cmdb > /data/backup/all_db.sql

7、备份数据库结构,不备份数据
格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 –no-data 数据库名1 数据库名2 数据库名3 > 文件名.sql

例如:mysqldump --no-data –databases db1 db2 cmdb > /data/backup/structure.sql