【问题标题】:error with storage 28 from storage engine with mysql使用mysql的存储引擎存储28错误
【发布时间】:2018-06-25 12:39:48
【问题描述】:

我遇到了存储问题。我收到了这个错误

 Got error 28 from storage engine 

我检查了存储容量,它仍然可用,但未满。这可能是什么原因?我检查了一切都没有成功

可能是我的主 mysql 数据目录用完了,或者在 mysql tmp 中。有人可以告诉我如何找到他们的位置以进行检查吗?

【问题讨论】:

    标签: mysql linux database centos


    【解决方案1】:

    可能是我的主 mysql 数据目录用完了,或者在 mysql tmp 中。有人能告诉我如何找到他们的位置以便检查吗?

    TL;DR

    发出以下命令分别检查服务器数据和临时目录的位置:

    SHOW GLOBAL VARIABLES LIKE 'datadir'
    SHOW GLOBAL VARIABLES LIKE 'tmpdir'
    

    这些变量的值通常是绝对路径(相对于任何运行服务器的chroot jail),但如果它们碰巧是相对路径,那么它们将相对于启动进程的工作目录服务器。

    但是……

    The MySQL Data Directory 中所述(强调添加):

    以下列表简要描述了通常在数据目录中找到的项目...

    可以通过重新配置服务器将前面列表中的某些项目重新定位到其他位置。 此外,--datadir 选项可以更改数据目录本身的位置。 对于给定的 MySQL 安装,检查服务器配置以确定是否已移动项目。

    因此,您可能还希望检查许多其他变量的值,包括:

    • pid_file
    • ssl_%
    • %_log_file
    • innodb_data_home_dir
    • innodb_log_group_home_dir
    • innodb_temp_data_file_path
    • innodb_undo_directory
    • innodb_buffer_pool_filename

    如果您的服务器没有响应...

    您还可以检查服务器的启动配置。

    Specifying Program Options 中所述,服务器的启动配置是“通过检查环境变量,然后通过处理选项文件,然后通过检查命令行”确定的,后面的选项优先于前面选项。

    如果您需要,该文档还列出了Option Files Read on Unix and Unix-Like Systems 的位置。请注意,服务器读取的那些文件的部分取决于服务器的启动方式,如Server Command Options 的第二和第三段所述。

    【讨论】:

    • 还有log_bin。二进制日志文件很可能会随着 INSERT 提交而增长。比 pid 文件或 InnoDB 重做日志等其他文件更有可能。
    • @eggyal 感谢您的评论,您能告诉我如何检查这些文件吗?
    • @Bill Karwin 我如何检查它们?是否有可能增加数据库存储的大小?
    • @nik, SELECT @@log_bin; 如果它是“1”(真),那么你的二进制日志会自动命名,它们位于datadir 下并共享同一个磁盘卷。如果@@log_bin 是绝对文件名,则它可能位于不同的磁盘卷上。
    • @Bill Karwin 它是 0。当我 SHOW GLOBAL VARIABLES LIKE 'datadir' 它带我到 /vol/db1/ 并且我有 mysql 和 temp 。如何增加删除不必要数据的大小?
    【解决方案2】:

    找到 MySQL 存储文件的位置后,在 shell 中运行命令:

    df -Ph <pathname>
    

    &lt;pathname&gt; 是您要测试的每个位置。有些可能在同一个磁盘卷上,所以当df 报告时它们会显示为相同。

    [vagrant@localhost ~]$ mysql -e 'select @@datadir'
    +-----------------+
    | @@datadir       |
    +-----------------+
    | /var/lib/mysql/ |
    +-----------------+
    
    [vagrant@localhost ~]$ df -Ph /var/lib/mysql
    Filesystem                       Size  Used Avail Use% Mounted on
    /dev/mapper/VolGroup00-LogVol00   38G  3.7G   34G  10% /
    

    这告诉我我的 datadir 的磁盘卷是根卷,包括顶级目录“/”及其下的所有内容。卷已满 10%,未使用 34G。

    如果您的 datadir 的卷达到 100%,那么当您插入新数据并且它需要扩展 MySQL 表空间或写入日志文件时,您将开始看到 errno 28 问题。

    在这种情况下,您需要弄清楚是什么占用了这么多空间。它可能在 MySQL 目录下,或者像我的情况一样,您的 datadir 可能是较大磁盘卷的一部分,所有其他文件都存在于其中。在这种情况下,系统上的任何文件堆积都可能导致磁盘填满。例如,日志文件或临时文件,即使它们与 MySQL 无关。

    我将从磁盘卷的顶部开始并使用du 找出哪些目录已满。

    [vagrant@localhost ~]$ sudo du -shx /*
    33M     /boot
    34M     /etc
    40K     /home
    28M     /opt
    4.0K    /tmp
    2.0G    /usr
    941M    /vagrant
    666M    /var
    

    注意:如果您的 df 命令告诉您您的 datadir 在单独的磁盘卷上,您将从该卷的挂载点开始。一个磁盘卷使用的空间不计入另一个磁盘卷。

    现在我看到/usr 占用了顶级目录中最多的空间。向下钻取,看看下面有什么占用空间:

    [vagrant@localhost ~]$ sudo du -shx /usr/*
    166M    /usr/bin
    126M    /usr/include
    345M    /usr/lib
    268M    /usr/lib64
    55M     /usr/libexec
    546M    /usr/local
    106M    /usr/sbin
    335M    /usr/share
    56M     /usr/src
    

    继续逐级向下钻取。

    通常罪魁祸首很清楚。就像你有一些巨大的 500G 日志文件 /var/log 在某个地方已经增长了几个月。

    一个典型的罪魁祸首是 http 服务器日志。


    你的cmets:

    听起来您的数据库存储有一个单独的存储卷。这很好。

    您刚刚在上面的问题中添加了du 输出。我看到在你的1.4T磁盘卷中,目前最大的单个文件是这样的:

    1020G   /vol/db1/mysql/_fool_Gerg_sql_200e_4979_main_16419_2_18.tokudb$
    

    这似乎是一个 TokuDB 表空间。这里有关于 TokuDB 如何处理完整磁盘的信息:https://www.percona.com/doc/percona-server/LATEST/tokudb/tokudb_faq.html#full-disks

    我不会删除这些文件。我对 TokuDB 不像对 InnoDB 那样熟悉,但我认为这些文件是重要的数据文件。如果删除它们,您将丢失部分数据,并可能损坏其余数据。

    我找到了这篇文章,里面详细解释了这些文件的用途:https://www.percona.com/blog/2014/07/30/examining-the-tokudb-mysql-storage-engine-file-structure/

    手册还说:

    从现有表中删除大量行然后关闭表可能会释放一些空间,但可能不会。删除行可能只是在 TokuDB 数据文件中留下未使用的空间(可用于新插入),而不是缩小文件(内部碎片)。

    因此您可以从表中删除行,但磁盘上的物理文件可能不会缩小。最终,您可以释放足够的空间,以便使用 ALTER TABLE &lt;tablename&gt; ENGINE=TokuDB ROW_FORMAT=TOKUDB_SMALL; 构建新的 TokuDB 数据文件(请参阅 https://dba.stackexchange.com/questions/48190/tokudb-optimize-table-does-not-reclaim-disk-space

    但这需要足够的可用磁盘空间来构建新表。

    所以我担心你把自己画到了一个角落里。您不再有足够的磁盘空间来重建您的大表。永远不要让可用磁盘空间小于重建最大表所需的空间。

    此时,您可能必须使用mysqldump 来转储最大表中的数据。不一定是整个表格,而只是您想要保留的内容(阅读mysqldump --where 选项)。然后DROP TABLE 完全删除那个大表。我认为这将释放磁盘空间,而使用 DELETE 则不会。

    您的 db1 卷上没有足够的空间来保存转储文件,因此您必须将它保存到另一个卷。看起来你在 /vol/cbgb1 上有更大的音量,但我不知道它是否已满。

    出于存档目的,我会转储整个内容。然后用一个子集再次转储。

    mkdir /vol/cbgdb1/backup
    mysqldump fool Gerg | gzip -c > /vol/cbgdb1/backup/Gerg-dump-full.sql.gz
    mysqldump fool Gerg --where "id > 8675309" | gzip -c > /vol/cbgb1/backup/Gerg-dump-partial.sql.gz
    

    我完全猜测--where 的论点。您必须决定如何选择部分转储。

    大表删除后,重新加载你转储的部分数据:

    gunzip -c /vol/cbgb1/backup/Gerg-dump-partial.sql.gz | mysql fool
    

    如果我在示例中给出的任何命令您还不熟悉,我建议您在尝试之前先学习它们。或者找一个更熟悉这些命令的人配对。

    【讨论】:

    • 非常感谢您的精彩解释。我可以很容易地理解第一部分。我做了df -Ph,我看到这个/dev/mapper/vg_db1-lv_db1,大小为1.4T,使用1.3T,使用了95%
    • 第二部分,我只看到363M /lib 和 4.8M /tmp 3.3G /usr 2.0G /var 16K /vol 挺大的,其他都还好
    • 我知道它安装在存储设备上并且足够大。我认为这与为数据库内容设置的大小有关。它已经运行多年了
    • 你看这个,我这里给了参数,它可能对错误给出更好的想法? stackoverflow.com/questions/48289203/…
    • 请看上面(我在我的mysql中粘贴了文件和大小,请检查是否可以删除它们?)
    猜你喜欢
    • 2016-11-10
    • 2023-03-03
    • 2012-05-24
    • 2012-05-17
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    相关资源
    最近更新 更多