mysql 部署

services:
  mysql:
    image: mysql:8.0.39
    environment:
      - MYSQL_ROOT_PASSWORD=xxxxxx
      - TZ=Asia/Shanghai
    healthcheck:
      retries: 10
      test:
        - CMD
        - mysqladmin
        - ping
        - -h
        - mysql
      timeout: 20s
    expose:
      - "3306"
    ports:
      - 3306:3306
    restart: always
    volumes:
      - ./mysql/initdb:/docker-entrypoint-initdb.d
      - ./mysql/conf/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
      - ./mysql/csv_data:/var/lib/mysql-files
      - ./mysql/data:/var/lib/mysql

自定义配置文件 my.cnf

[mysqld]
# 允许在此目录下使用 LOAD DATA
secure-file-priv=/var/lib/mysql-files

# 缓冲池大小,建议设为宿主机空闲内存的 50%-70%
innodb_buffer_pool_size=4G  
# 放宽事务日志刷盘频率,极大提升写入速度(导入完成后建议改回默认的 1)
innodb_flush_log_at_trx_commit=2 
# 临时关闭双写缓冲,加快速度(导入完成后建议改回默认的 1)
innodb_doublewrite=0

# 日志文件大小增大,减少 checkpoint 频率
innodb_log_file_size = 2G
innodb_log_files_in_group = 3

# 增大写缓冲区
innodb_write_io_threads = 16
innodb_read_io_threads = 4

# 增大批量插入缓存
bulk_insert_buffer_size = 512M

# 关闭自适应哈希索引(大量写入时反而有开销)
innodb_adaptive_hash_index = OFF

数据导入

方法一

mysqlsh 工具

首先进入容器,执行下面代码,并预先创建一张表

# 登录
mysql -uroot -pxxxxxx

SET GLOBAL local_infile = 1;

exit;

然后执行数据导入

mysqlsh root@localhost -pxxxxxx --js

util.importTable("/var/lib/mysql-files/data-1e.csv", {
    schema: "数据库名", 
    table: "表名",
    dialect: "csv",
    fieldsTerminatedBy: ",",     // CSV 分隔符
    fieldsEnclosedBy: '"',       // 字符串包含符
    linesTerminatedBy: "\n",     // 换行符 (Windows生成的可能是 \r\n)
    skipRows: 1,                 // 跳过第1行
    threads: 8,                  // 开启8个线程并行导入
    bytesPerChunk: "100M",       // 每个线程一次处理 100MB 数据
    maxRate: "0"                 // 不限制速度
})

方法二

批量 load data infile

# 分割数据
cd ./mysql/csv_data
split -l 5000000 massive_data.csv part_ --additional-suffix=.csv
# or
head -1 huge_file.csv > header.csv  # 保存标题行
tail -n +2 massive_data.csv | split -l 1000000 - parts_

docker exec -it <你的容器名称> bash
cd /var/lib/mysql-files
for file in part_*.csv; do
    echo "Importing $file..."
    mysql -uroot -pxxxxxx <数据库名> -e "LOAD DATA INFILE '/var/lib/mysql-files/$file' INTO TABLE <表名> FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;"
done

更多推荐