我们之前用的mysqldump..看起来速度最差
现在用的mysqlshell, 是mysql官方推出的,用C写的一个工具~
20241014
mysqlsh –js -utaskon_rw_rolling -ppassport -h172.22.0.33 -P3306 -e “util.dumpSchemas([‘taskon_community’], ‘/data/mysql-to-ck/newversion/clickhouse-sink-connector/sink-connector/python/downloadtaskonprod_community_daily’);” 这样导数据会导致cpu过高,mysql压力也很大,如何能降低数据导出的频次?花费的时间可是适度延长
在使用 mysqlsh 导出 MySQL 数据时,如果 CPU 负载过高且 MySQL 压力较大,你可以通过以下几种方式来降低数据导出的频次,同时适度延长数据导出的时间。这些方法可以帮助减少对数据库的冲击。
1. 使用 --threads 参数控制导出并发线程数
mysqlsh 的 util.dumpSchemas 方法支持 threads 参数,可以通过减少并发线程数来降低对系统资源(CPU、磁盘I/O等)的占用。
你可以通过 maxThreads 参数设置最大并发线程数,减少并发度来减轻 MySQL 的负载:
1 | mysqlsh --js -utaskon_rw_rolling -ppassport -h172.22.0.33 -P3306 \ |
此处 threads: 2 设置导出任务最多使用2个线程,默认值可能是系统CPU逻辑核心数。你可以根据服务器的负载情况尝试不同的线程数。
2. 使用 --compress 参数减少 I/O
数据导出过程中,I/O 也是数据库和系统的压力来源。可以启用压缩来减少 I/O 负担:
1 | mysqlsh --js -utaskon_rw_rolling -ppassport -h172.22.0.33 -P3306 \ |
compress: true 会启用数据压缩来减少磁盘和网络I/O的压力,代价是会稍微增加一些CPU开销,但整体效果通常是正面的。
3. 分批导出数据
如果数据库表特别大,可以分批导出数据,避免一次性全量导出。你可以使用定期小批量导出的方法,结合 --where 参数来过滤数据,或者在应用层实现分批导出逻辑。例如导出过去一天的数据:
1 | mysqlsh --js -utaskon_rw_rolling -ppassport -h172.22.0.33 -P3306 \ |
这样可以减少一次性导出的数据量,降低数据库压力。
4. 使用 --no-locks 降低表锁定时间
util.dumpSchemas 默认会锁定表以确保一致性。如果你可以容忍一些微小的不一致性(例如对实时性要求不高的场景),可以通过 consistent: false 选项禁用表锁定:
1 | mysqlsh --js -utaskon_rw_rolling -ppassport -h172.22.0.33 -P3306 \ |
这会减少表锁定时间,从而降低对数据库的负载。
5. 调整 MySQL 配置
如果你有权限修改 MySQL 的配置文件,可以考虑以下几种优化以减少 MySQL 压力:
innodb_flush_log_at_trx_commit
将这个值从1改为2或0,可以减少磁盘I/O。这个配置决定了事务提交时日志的刷新频率。innodb_buffer_pool_size
确保innodb_buffer_pool_size足够大,以便更多数据能够缓存到内存中,减少磁盘I/O。max_connections
确保你的 MySQL 实例有足够的连接数上限,以处理导出任务和其他应用的并发连接。
总结
可以通过以下几点来降低 MySQL 导出时的压力:
- 降低并发线程数,使用
{ threads: N }参数。 - 启用数据压缩,使用
{ compress: true }参数减少I/O。 - 分批导出数据,通过
where语句控制每次导出的数据量。 - 禁用表锁定,使用
{ consistent: false }来减少锁定时间。 - 优化MySQL配置,特别是I/O和内存相关的参数。
根据你的实际情况,可以灵活组合这些方法,来减少导出数据时的负载。
能否改为按表导?每导出一张表sleep几秒钟?
你可以通过脚本的方式按表导出,并在导出每张表后使用 sleep 函数暂停几秒钟。这样可以有效降低数据库的负载,同时让导出过程更平稳。
下面是一个示例脚本,展示如何按表导出,并在每次导出后暂停几秒钟(假设你使用的是 bash 脚本):
示例 Bash 脚本
1 |
|
脚本说明
MySQL 登录信息:
你需要提供正确的用户名($USER)、密码($PASSWORD)、主机地址($HOST)、端口($PORT)以及数据库名称($SCHEMA)。获取表列表:
脚本使用以下命令获取数据库中的所有表:1
TABLES=$(mysqlsh --js -u$USER -p$PASSWORD -h$HOST -P$PORT -e "var schema = session.getSchema('$SCHEMA'); schema.getTables().map(table => table.getName());")
这会返回一个表名列表。
按表导出:
使用util.dumpTables()方法导出每张表,并将其保存到指定的输出目录。1
2mysqlsh --js -u$USER -p$PASSWORD -h$HOST -P$PORT \
-e "util.dumpTables(['$TABLE'], '$OUTPUT_DIR/$TABLE')"导出后等待:
每次导出一张表后,脚本会调用sleep $SLEEP_SECONDS,暂停几秒(你可以通过修改$SLEEP_SECONDS来调整等待时间)。错误处理:
如果某张表导出失败,脚本会跳过等待并继续导出下一个表。通过检查上一条命令的返回码$?实现这个逻辑。
运行脚本
将这个脚本保存为一个
.sh文件,例如export_tables.sh。给予脚本执行权限:
1
chmod +x export_tables.sh
运行脚本:
1
./export_tables.sh
其他优化
并发控制:
如果希望进一步控制并发度,可以在util.dumpTables函数中添加threads参数,例如{ threads: 2 }来限制导出时的线程数。错误日志:
你可以将导出日志保存到文件:1
./export_tables.sh > export_log.txt 2>&1
这样可以在后台查看导出过程是否有错误。
总结
通过这种按表导出并在每次导出后 sleep 几秒的方式,可以有效降低导出过程中的数据库负载,并让导出过程更加平滑。根据你的具体需求,可以调整 sleep 时间和导出参数。
原文链接: https://dashen.tech/2018/08/31/MySQL同步工具比选/
版权声明: 转载请注明出处.