【PGCCC】commit_delay 对性能的提升:PostgreSQL 基准测试

在这里插入图片描述

通过禁用参数可以来调整事务工作负载synchronous_commit。该措施有惊人效果。但在操作系统崩溃期间丢失已提交事务的可能性使其成为许多应用程序无法启动的因素。因此我决定写下来。

WAL 刷新是事务数据库工作负载的瓶颈

为了确保已提交的事务不会丢失,PostgreSQL 必须确保事务的WAL已刷新到磁盘,然后才能向客户端报告成功。如果数据库工作负载主要由小数据修改组成,则这些事务产生的IOPS可能会使磁盘饱和,即使写入的数据量适中。

参数对commit_delay可以commit_siblings通过减少这些 WAL 刷新所需的 IOPS 数量来缓解瓶颈。

commit_delay和如何commit_siblings工作?

您可以通过将其设置为大于零的值来激活该功能commit_delay。每当事务在提交期间达到将 WAL 刷新到磁盘的点时,它首先检查当前有多少其他事务处于活动状态。如果至少有其他commit_siblings事务处于打开状态并且没有等待锁定,PostgreSQL 不会立即刷新 WAL,而是等待commit_delay几微秒。经过该延迟后,其他一些事务可能已达到准备刷新 WAL 的点。然后,所有这些后端都可以在单个 I/O 操作中执行其 WAL 刷新。

commit_delay调整起来并不容易,因为延迟会使事务耗时更长。另一方面,如果选择的值太低,则在延迟过去时可能没有其他事务准备就绪,并且您无法减少执行的 IOPS 数量。

commit_delay基准设置

基准测试在我的 ASUS ZenBook UX433F 笔记本上运行,该笔记本具有本地 NVME 磁盘、8 个 CPU 核心和 16GB RAM。我设置了sh

# global settings pid_dir: '~/.pg_chameleon/pid/' log_dir: '~/.pg_chameleon/logs/' log_dest: file log_level: info log_days_keep: 10 rollbar_key: '' rollbar_env: '' dump_json: No alert_log_collection_enable: false alert_log_kafka_server: 127.0.0.1:9092 alert_log_kafka_topic: my_log # type_override allows the user to override the default type conversion # into a different one. type_override: # "tinyint(1)": # override_to: boolean # override_tables: # - "*" # specify the compress properties when creating tables compress_properties: compresstype: 0 compress_level: 0 compress_chunk_size: 4096 compress_prealloc_chunks: 0 compress_byte_convert: false compress_diff_convert: false # postgres destination connection pg_conn: host: "localhost" port: "5432" user: "usr_replica" password: "never_commit_passwords" database: "db_replica" charset: "utf8" params: # maintenance_work_mem: "1G" # param1: value1 # param2: value2 sources: mysql: readers: 4 writers: 4 retry: 3 db_conn: host: "localhost" port: "3306" user: "usr_replica" password: "never_commit_passwords" charset: 'utf8' connect_timeout: 10 schema_mappings: delphis_mediterranea: loxodonta_africana limit_tables: - delphis_mediterranea.foo skip_tables: - delphis_mediterranea.bar enable_compress: No compress_tables: - delphis_mediterranea.foo grant_select_to: - usr_readonly lock_timeout: "120s" my_server_id: 100 replica_batch_size: 10000 replay_max_rows: 10000 batch_retention: '1 day' copy_max_memory: "300M" copy_mode: 'file' out_dir: /tmp csv_dir: /tmp contain_columns: No column_split: ',' sleep_loop: 1 on_error_replay: continue on_error_read: continue auto_maintenance: "disabled" index_parallel_workers: 2 gtid_enable: false type: mysql skip_events: insert: - delphis_mediterranea.foo # skips inserts on delphis_mediterranea.foo delete: - delphis_mediterranea # skips deletes on schema delphis_mediterranea update: keep_existing_schema: No migrate_default_value: Yes mysql_restart_config: No is_create_index: Yes index_dir: '~/.pg_chameleon/index/' is_skip_completed_tables: No with_datacheck: No slice_size: 100000 csv_files_threshold: csv_dir_space_threshold:
最新发布
07-05
这是 **pg_chameleon** 工具的完整配置文件(YAML 格式),用于从 **MySQL** 迁移数据到 **PostgreSQL**(或 openGauss)。配置分为全局设置、目标库连接、源库连接和迁移规则四大部分,支持离线迁移和实时同步(基于 binlog)。以下是详细解析: --- ### **1. 全局设置(Global Settings)** ```yaml pid_dir: '~/.pg_chameleon/pid/' # 进程 ID 文件存储目录 log_dir: '~/.pg_chameleon/logs/' # 日志文件存储目录 log_dest: file # 日志输出目标(file=文件,stdout=控制台) log_level: info # 日志级别(debug/info/warning/error) log_days_keep: 10 # 日志保留天数 rollbar_key: '' # Rollbar 错误监控服务 API Key(未启用) rollbar_env: '' # Rollbar 环境名称(未启用) dump_json: No # 是否导出迁移过程为 JSON(否) alert_log_collection_enable: false # 是否启用日志告警收集(否) alert_log_kafka_server: 127.0.0.1:9092 # Kafka 服务器地址(用于日志告警) alert_log_kafka_topic: my_log # Kafka 主题名称 ``` #### **关键作用** - 控制工具的运行行为(如日志、进程管理)。 - 支持将日志发送到 Kafka 等外部系统(当前未启用)。 --- ### **2. 类型覆盖(Type Override)** ```yaml type_override: # "tinyint(1)": # MySQL 类型 # override_to: boolean # 覆盖为 PostgreSQL 的 boolean 类型 # override_tables: # 适用表范围 # - "*" # 所有表 ``` #### **作用** - 自定义 MySQL 数据类型到 PostgreSQL 的映射规则。 - **示例场景**:将 MySQL 的 `tinyint(1)`(通常用于布尔值)自动转换为 PostgreSQL 的 `boolean` 类型。 - **当前状态**:配置被注释,未生效。 --- ### **3. 压缩属性(Compress Properties)** ```yaml compress_properties: compresstype: 0 # 压缩类型(0=不压缩) compress_level: 0 # 压缩级别(0-9,0=不压缩) compress_chunk_size: 4096 # 压缩块大小(字节) compress_prealloc_chunks: 0 # 预分配压缩块数量 compress_byte_convert: false # 是否转换字节序 compress_diff_convert: false # 是否转换差分数据 ``` #### **作用** - 配置迁移过程中数据的压缩选项(当前未启用压缩)。 - **适用场景**:迁移大表时减少网络传输量(需 PostgreSQL 支持压缩扩展)。 --- ### **4. PostgreSQL 目标连接(pg_conn)** ```yaml pg_conn: host: "localhost" # PostgreSQL 服务器地址 port: "5432" # PostgreSQL 端口 user: "usr_replica" # 连接用户名 password: "never_commit_passwords" # 连接密码(安全提示:实际使用时应从环境变量或密钥管理服务读取) database: "db_replica" # 目标数据库名 charset: "utf8" # 字符集 params: # 额外连接参数(可选) # maintenance_work_mem: "1G" # 示例:设置维护内存为 1GB # param1: value1 # param2: value2 ``` #### **关键参数** - **`user`/`password`**:需确保该用户有权限在目标库创建表和插入数据。 - **`params`**:可配置 PostgreSQL 的运行时参数(如 `work_mem`、`maintenance_work_mem`)。 --- ### **5. MySQL 源库连接(sources → mysql)** ```yaml sources: mysql: readers: 4 # 读取线程数(并行读取 MySQL 数据) writers: 4 # 写入线程数(并行写入 PostgreSQL) retry: 3 # 操作失败后的重试次数 db_conn: # MySQL 连接配置 host: "localhost" port: "3306" user: "usr_replica" password: "never_commit_passwords" charset: 'utf8' connect_timeout: 10 # 连接超时时间(秒) schema_mappings: # 模式(Schema)映射 delphis_mediterranea: loxodonta_africana # 将 MySQL 的 delphis_mediterranea 映射为 PostgreSQL 的 loxodonta_africana limit_tables: # 仅迁移指定表 - delphis_mediterranea.foo skip_tables: # 跳过指定表 - delphis_mediterranea.bar enable_compress: No # 是否启用数据压缩(当前禁用) compress_tables: # 压缩表列表(需 enable_compress=Yes 才生效) - delphis_mediterranea.foo grant_select_to: # 授权只读用户访问迁移后的表 - usr_readonly lock_timeout: "120s" # 获取锁的超时时间 my_server_id: 100 # MySQL 复制中的服务器 ID(实时同步时使用) replica_batch_size: 10000 # 每次批量复制的行数 replay_max_rows: 10000 # 每次重放的行数 batch_retention: '1 day' # 批量数据的保留时间 copy_max_memory: "300M" # COPY 命令的最大内存使用量 copy_mode: 'file' # COPY 模式(file=通过文件传输,direct=直接传输) out_dir: /tmp # 临时文件输出目录 csv_dir: /tmp # CSV 文件存储目录 contain_columns: No # 是否包含列名在 CSV 文件中 column_split: ',' # CSV 文件的列分隔符 sleep_loop: 1 # 循环间隔(秒) on_error_replay: continue # 重放错误时的行为(continue=继续,abort=终止) on_error_read: continue # 读取错误时的行为 auto_maintenance: "disabled" # 是否自动维护(如真空表) index_parallel_workers: 2 # 创建索引的并行工作线程数 gtid_enable: false # 是否启用 GTID(全局事务标识符) type: mysql # 源数据库类型 skip_events: # 跳过特定事件 insert: - delphis_mediterranea.foo # 跳过对 delphis_mediterranea.foo 的 INSERT 操作 delete: - delphis_mediterranea # 跳过对 delphis_mediterranea 模式的 DELETE 操作 update: # 未配置 UPDATE 跳过规则 keep_existing_schema: No # 如果目标库已存在同名表,是否保留(No=覆盖) migrate_default_value: Yes # 是否迁移列的默认值 mysql_restart_config: No # 是否重启 MySQL 配置(通常不需要) is_create_index: Yes # 是否创建索引 index_dir: '~/.pg_chameleon/index/' # 索引文件存储目录 is_skip_completed_tables: No # 是否跳过已迁移完成的表 with_datacheck: No # 是否进行数据一致性校验 slice_size: 100000 # 数据分片大小(行数) csv_files_threshold: # CSV 文件大小阈值(未配置) csv_dir_space_threshold: # CSV 目录空间阈值(未配置) ``` #### **关键参数解析** 1. **`schema_mappings`**: - 将 MySQL 的 `delphis_mediterranea` 模式映射为 PostgreSQL 的 `loxodonta_africana` 模式。 - **用途**:解决 MySQL 和 PostgreSQL 中模式命名差异的问题。 2. **`limit_tables` 和 `skip_tables`**: - 仅迁移 `delphis_mediterranea.foo` 表,跳过 `delphis_mediterranea.bar` 表。 - **用途**:选择性迁移部分表。 3. **`skip_events`**: - 跳过对 `delphis_mediterranea.foo` 表的 INSERT 操作和对 `delphis_mediterranea` 模式的 DELETE 操作。 - **用途**:在实时同步中排除特定操作(如避免删除生产数据)。 4. **`copy_mode: 'file'`**: - 通过文件传输数据(而非直接网络传输),适用于大表迁移。 - **替代方案**:`copy_mode: 'direct'`(直接传输,速度更快但可能不稳定)。 5. **`batch_retention: '1 day'`**: - 保留批量数据 1 天,用于故障恢复。 - **用途**:避免重复迁移已处理的数据。 --- ### **6. 配置文件的典型用途** 1. **离线迁移**: - 从 MySQL 导出数据,转换语法后导入 PostgreSQL。 - 示例命令: ```bash pg_chameleon migrate --config /path/to/config.yaml --source mysql --target postgres ``` 2. **实时同步**: - 通过解析 MySQL 的 binlog 实现增量同步(需配置 `my_server_id` 和 `gtid_enable`)。 - 示例命令: ```bash pg_chameleon start_replica --config /path/to/config.yaml --source mysql ``` --- ### **7. 常见问题与优化** #### **Q1: 如何启用类型覆盖?** - 取消 `type_override` 部分的注释,并修改为实际需求: ```yaml type_override: "tinyint(1)": override_to: boolean override_tables: - "my_table" # 仅对 my_table 生效 ``` #### **Q2: 如何提升大表迁移性能?** - 调整以下参数: ```yaml sources: mysql: readers: 8 # 增加读取线程 writers: 8 # 增加写入线程 copy_max_memory: "1G" # 加大 COPY 内存 slice_size: 500000 # 增大分片大小 ``` #### **Q3: 如何安全存储密码?** - 避免在配置文件中明文存储密码,可通过以下方式: 1. 使用环境变量: ```yaml pg_conn: password: "${DB_PASSWORD}" # 从环境变量读取 ``` 2. 使用密钥管理服务(如 AWS Secrets Manager)。 #### **Q4: 如何验证配置是否生效?** - 运行测试命令: ```bash pg_chameleon test_connection --config /path/to/config.yaml --source mysql pg_chameleon test_connection --config /path/to/config.yaml --target postgres ``` 输出应显示 `Connection to MySQL successful` 和 `Connection to PostgreSQL successful`。 #### **Q5: 如何跳过所有 UPDATE 操作?** - 在 `skip_events` 中添加: ```yaml skip_events: update: - "*" # 跳过所有 UPDATE 操作 ``` --- ### **8. 完整配置示例(优化版)** ```yaml pid_dir: '/var/run/pg_chameleon' log_dir: '/var/log/pg_chameleon' log_level: debug type_override: "tinyint(1)": override_to: boolean override_tables: - "*" compress_properties: compresstype: 1 # 启用压缩(需 PostgreSQL 扩展支持) compress_level: 3 pg_conn: host: "192.168.1.100" port: "5432" user: "replica_user" password: "${DB_PASSWORD}" # 从环境变量读取 database: "migrated_db" params: maintenance_work_mem: "1GB" sources: mysql: readers: 8 writers: 8 db_conn: host: "192.168.1.200" port: "3306" user: "replica_user" password: "${MYSQL_PASSWORD}" schema_mappings: my_mysql_db: my_postgres_db limit_tables: - my_mysql_db.large_table skip_tables: - my_mysql_db.log_* copy_mode: 'file' copy_max_memory: "500M" slice_size: 1000000 ``` --- ### **总结** | 配置段 | 作用 | |----------------------|----------------------------------------------------------------------| | **Global Settings** | 控制日志、进程管理等工具行为。 | | **Type Override** | 自定义 MySQL 到 PostgreSQL 的数据类型映射。 | | **Compress** | 配置迁移数据的压缩选项(减少网络传输)。 | | **pg_conn** | 定义 PostgreSQL 目标数据库的连接参数和权限。 | | **sources → mysql** | 定义 MySQL 源库的连接参数、迁移规则和性能调优选项。 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值