zoukankan      html  css  js  c++  java
  • Docker容器MySQL5.7的ibdata1过大问题解决

    环境信息

    1、宿主机:Ubuntu 20.04.2 LTS
    2、Docker: 20.10.6
    3、镜像版本: mysql:5.7.19

    简述

    上一节,在《Docker容器MySQL5.7系统表空间数据文件ibdata1》 中,分析如何使用 innochecksum 工具来分析了什么被存储到了 ibdata1 里。我们发现 Undo log page 占据了 ibdata1 中 93% 的空间。

    那么,有什么办法回收已使用的空间吗?

    没有,目前还没有一个容易并且快速的方法。InnoDB 表空间从不收缩...
    当你删除一些行,这个页被标为已删除稍后重用,但是这个空间从不会被回收。唯一的方法是使用新的 ibdata1 启动数据库。要做这个你应该需要使用 mysqldump 做一个逻辑全备份,然后停止 MySQL 并删除所有数据库、ib_logfile*ibdata* 文件。当你再启动 MySQL 的时候将会创建一个新的共享表空间。然后恢复逻辑备份。
    不过 Docker 的话,还是删除整个文件夹再重建一个新的空文件夹更方便,否则重启容器时,会因为 datadir 不为空,导致无法正常初始化而失败。

    0.前置准备

    重启服务: 首先,我们把 Docker 容器的 MySQL 服务停掉了,现在我们先重新拉起:

    docker ps -a
    docker restart 容器ID
    

    登入容器 Bash: 然后,再次登入 Docker 容器的 Bash:

    docker container exec -it 容器ID /bin/bash
    

    因为我们的主机没有安装对应 MySQL 软件,所以登入容器执行。

    1.逻辑全备份

    cd /var/lib/mysql
    mysqldump -uroot -p --add-drop-table --all-databases > all.sql
    

    /var/lib/mysql 是 MySQL 当前的 datadir 数据文件路径。

    • --all-databases 备份所有的数据库。

    • --add-drop-table 在所有的 CREATE 语句前加上 DROP 语句。

    • 那为什么要添加 -uroot -p 呢?是为了解决权限问题。

    • > 是输出重定向符号,表示将左边的内容输出到右边的文件中。

    2.清除并重建数据文件

    清除之前,建议停止当前 Docker 容器:

    docker stop 容器ID
    

    然后 cd 进入在Docker容器之/var/lib/mysql宿主机的映射文件夹下:

    比如我用 docker container inspect 查看到我的宿主机映射目录是 /var/lib/docker/volumes/6cabb5980aa5e859e4fe389f8ed6dcfede8c126b696edb8e777addac800996e1/_data

    docker container inspect 容器ID | grep Mounts -A 20
    

    ★ 先把 all.sql 转移走

    cd /var/lib/docker/volumes/6cabb5980aa5e859e4fe389f8ed6dcfede8c126b696edb8e777addac800996e1/_data
    mv all.sql ~/
    

    ★ 移除 _data 文件夹

    cd /var/lib/docker/volumes/6cabb5980aa5e859e4fe389f8ed6dcfede8c126b696edb8e777addac800996e1/
    rm -rf _data/
    mkdir _data
    

    ★ 再把 all.sql 放回映射的数据文件夹

    cd /var/lib/docker/volumes/6cabb5980aa5e859e4fe389f8ed6dcfede8c126b696edb8e777addac800996e1/_data
    mv ~/all.sql ./
    

    然后,重启 Docker 服务。重复 0.前置准备 中的操作,当你再启动 MySQL 的时候将会创建一个新的共享表空间。

    我们可以对比一下 ibdata1 的大小变化,首先是重建前:

    然后,是重建后:

    3.恢复逻辑全备份

    再次进入 Docker 中的 MySQL 容器 Bash 中:

    cd /var/lib/mysql
    mysql -uroot -p < all.sql
    

    备份恢复之后,就可以删除 all.sql 了。

    参考文档

    1、《解决ibdata1数据库过大的问题》

    2、《MySQL的ibdata1详解》

  • 相关阅读:
    持久化 XSS:ServiceWorkers 利用
    preg_replace引发的phpmyadmin(4.3.0-4.6.2)命令执行漏洞
    seacms6.5 注入漏洞1
    渗透中常见的网络端口
    composer安装指定版本的ThinkPHP
    php-fpm以root权限运行
    ntp网络时间服务器地址
    查看*.dll文件是32位还是64位的方法
    从经典案例学习SSRF漏洞的产生原因和修复方法
    Apache将AllowOverride设置为All以后出现403 Forbidden的解决方法
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/14836482.html
Copyright © 2011-2022 走看看