mysqldump最佳实践(1)
2023-01-25 22:16 abce 阅读(286) 评论(0) 编辑 收藏 举报1.空间需求
首先,重要的是要确保目标数据库有足够的空间来保存导入的数据。具体来说,如果在目标MySQL数据库上启用了二进制日志,则需要非常谨慎,因为导入数据时生成的二进制日志可能与数据本身的大小几乎相同。如果希望在一台服务器上恢复数据并进行复制,则需要二进制日志。在这种情况下,最好将目标数据库大小规划为源数据库大小的两倍以上。
确保生成mysqldump输出文件的卷上有足够的可用空间也很重要。如果没有这些预防措施,可能会看到转储或恢复在长时间运行后由于空间不足而失败,这将损失生产时间和精力。
2.sql_mode
sql_mode的设置,决定了mysql server的sql语句语法和为操作执行的数据验证检查。确保源MySQL服务器和目标MySQL服务器的sql_mode彼此兼容是很重要的,否则在恢复所获取的dump时可能会遇到失败。
用一个例子来说明这一点。假设在源库有一个表,其中有一个日期列,含有日期为零的条目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | mysql> show create table sched; --------------------------------------------------------+ | Table | Create Table | --------------------------------------------------------+ | sched | CREATE TABLE `sched` ( `id` int (11) DEFAULT NULL , `ts` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | + -------+--------------------------------------------------------------------------------------------------------------------- mysql> select * from sched; + ------+------------+ | id | ts | + ------+------------+ | 1 | 2020-01-12 | | 2 | 0000-00-00 | + ------+------------+ |
假设在源库没有开启严格的sql_mode(即没有开启no_zero_date),而目标端却开启了严格模式,数据还原的时候就会发生失败:
1 | ERROR 1292 (22007) at line 40: Incorrect date value: '0000-00-00' for column 'ts’' at row 2 |
mysqldump执行备份的时候,如果使用compact选项,你可能就会遇到这种典型的错误。
如果禁用了compact(默认就是禁用的)选项,mysqldump就不会遇到这些错误,因为在dump的时候会生成以下语句:
1 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE,SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ ; |
这表示在还原表数据之前,将sql_mode设置成了no_auto_value_on_zero。
3.Unique_checks和foreign_key_checks
缺省情况下(如果你没有使用compact选项),mysqldump还会做如下设置:
1 2 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ ; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ ; |
如果注释所示,你可以在会话级别临时关闭唯一性检查,从而加快数据还原。对于大表,可能会节省很多的I/O,因为innodb可以借助change buffer批量写二级辅助索引。
如果表上有外键约束,在还原会话中取消外键检查可以加速还原操作。对于大表,可以节省很多的I/O。
禁用FOREIGN_KEY_CHECKS还将有助于避免在恢复操作中由于外部键约束检查而导致的错误。每当创建一个带有外键约束的表时,MySQL期望由外键引用的父表已经存在。这是一个问题,因为mysqldump实用程序按字母顺序转储表。
来通过一个例子来说明这一点。在源数据库中,有两个表:
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE `solution_table` ( `num1` int (11) NOT NULL , `num2` int (11) DEFAULT NULL , PRIMARY KEY (`num1`)); CREATE TABLE `ref_table` ( ` key ` int (11) DEFAULT NULL , `ref_num` int (11) DEFAULT NULL , KEY `ref_num` (`ref_num`), CONSTRAINT `ref_num_ibfk_1` FOREIGN KEY (`ref_num`) REFERENCES `solution_table` (`num1`) ) |
ref_table有个外键约束指向表solution_table。按照字母顺序,mysqldump会先dump出ref_table。在还原过程中,就会遇到如下的错误:
1 | ERROR 1215 (HY000) at line 50: Cannot add foreign key constraint - |
在创建表ref_table的时候就会发生上面的错误。
总结来说,如果你指定了--compact选项,就要注意上面的这些问题。
4.权限需求
mysqldump转储数据库所需的最小权限是该数据库上的SELECT。然而,如果你的数据库有视图,你也需要SHOW VIEW权限,因为mysqldump总是转储视图和数据库的表。假设你没有SHOW VIEW权限,那么mysqldump将失败:
1 | mysqldump: Couldn 't execute ' show create table `ivew` ': SHOW VIEW command denied to user ‘dumpuser’@' 172.31.18.79 ' for table ' iview' (1142) |
另一点值得注意的是,如果你的dumpuser仅对数据库的某个特定表具有SELECT权限,mysqldump将仅为该特定表转储数据,并自动忽略任何其他表或视图。因此,请确保执行mysqldump的用户预先拥有所有适当的特权,以避免在以后的时间出现任何意外或失败。
5.Max_allowed_packet
mysql处理的最大通信包由max_allowed_packet决定。在导入上下文中,通信包是在恢复期间发送给MySQL服务器的一条SQL语句,或者是在转储期间发送给客户端的一行。
mysqldump的max_allowed_packet的默认值是24MB。如果mysqldump收到的数据包大于这个值,那么你可能会遇到这样的错误:
1 | mysqldump: Error 2020: Got packet bigger than 'max_allowed_packet' bytes when dumping table `huge1` at row: 2. |
因此,确保mysqldump使用与源MySQL实例上配置的max_allowed_packet相同或更大的值。
在调用mysqldump时,可以使用——max-allowed-packet=value标记指定该选项。
在恢复转储时,确保目标服务器的max_allowed_packet大小足够大,可以接收转储文件中的数据包。
否则,在恢复转储的过程中,将看到一个错误消息:
1 | ERROR 2006 (HY000) at line 70: MySQL server has gone away |
这个错误可能有点误导性,因为你可能认为MySQL服务器已经关闭或崩溃了。但是,这只是意味着服务器收到了一个比它配置的max_allowed_packet大小更大的数据包。
同样,最佳实践是确保目标服务器的max_allowed_packet值与源服务器中的值相同。这也是一个重要的设置,可以提前检查和适当设置,而不是在以后面对错误。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2016-01-25 interblock corruption & intrablock corruption