MariaDB
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> MariaDB

Cơ sở dữ liệu MySQL của tôi đã hết dung lượng đĩa

Khi máy chủ MySQL hết dung lượng đĩa, bạn sẽ thấy một trong các lỗi sau trong ứng dụng của mình (cũng như trong nhật ký lỗi MySQL):

ERROR 3 (HY000) at line 1: Error writing file '/tmp/AY0Wn7vA' (Errcode: 28 - No space left on device)

Đối với nhật ký nhị phân, thông báo lỗi trông giống như sau:

[ERROR] [MY-000035] [Server] Disk is full writing './binlog.000019' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

Đối với nhật ký chuyển tiếp, thông báo lỗi trông giống như sau:

[ERROR] [MY-000035] [Server] Disk is full writing './relay-bin.000007' (OS errno 28 - No space left on device). Waiting for someone to free space... Retry in 60 secs. Message reprinted in 600 secs.

Đối với nhật ký truy vấn chậm, bạn sẽ thấy một thông báo lỗi như sau:

[ERROR] [MY-011263] [Server] Could not use /var/log/mysql/mysql-slow.log for logging (error 28 - No space left on device). Turning logging off for the server process. To turn it on again: fix the cause, then either restart the query logging by using "SET GLOBAL SLOW_QUERY_LOG=ON" or restart the MySQL server.

Đối với InnoDB, nó trông giống như vậy:

[ERROR] [MY-012144] [InnoDB] posix_fallocate(): Failed to preallocate data for file ./#innodb_temp/temp_8.ibt, desired size 16384 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/8.0/en/operating-system-error-codes.html
[Warning] [MY-012638] [InnoDB] Retry attempts for writing partial data failed.
[ERROR] [MY-012639] [InnoDB] Write to file ./#innodb_temp/temp_8.ibt failed at offset 81920, 16384 bytes should have been written, only 0 were written. Operating system error number 28. Check that your OS and file system support files of this size. Check also that the disk is not full or a disk quota exceeded.
[ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'
[Warning] [MY-012145] [InnoDB] Error while writing 16384 zeroes to ./#

Tất cả chúng đều báo cáo cùng một số mã lỗi là 28. Ngoài ra, chúng ta có thể sử dụng mã lỗi để xem lỗi thực tế với lệnh perror:

$ perror 28
OS error code  28: No space left on device

Điều trên chỉ đơn giản có nghĩa là máy chủ MySQL hết dung lượng đĩa và phần lớn thời gian MySQL bị dừng hoặc bị đình trệ tại thời điểm này. Trong bài đăng trên blog này, chúng ta sẽ xem xét các cách giải quyết vấn đề này cho MySQL chạy trong môi trường dựa trên Linux.

Khắc phục sự cố

Trước hết, chúng ta phải xác định phân vùng đĩa nào đã đầy. MySQL có thể được cấu hình để lưu trữ dữ liệu trên một đĩa hoặc phân vùng khác. Nhìn vào đường dẫn như đã nêu trong lỗi để bắt đầu. Trong ví dụ này, thư mục của chúng tôi được đặt ở vị trí mặc định, / var / lib / mysql nằm dưới phân vùng /. Chúng ta có thể sử dụng lệnh df và chỉ định đường dẫn đầy đủ đến datadir để lấy phân vùng mà dữ liệu được lưu trữ:

$ df -h /var/lib/mysql
Filesystem      Size Used Avail Use% Mounted on
/dev/sda1        40G 40G 20K 100% /

Điều trên có nghĩa là chúng ta phải giải phóng một số không gian trong phân vùng gốc.

Giải pháp tạm thời

Cách giải quyết tạm thời là giải phóng một số không gian đĩa để MySQL có thể ghi vào đĩa và tiếp tục hoạt động. Những điều chúng ta có thể làm nếu gặp phải loại vấn đề này liên quan đến:

  • Xóa các tệp không cần thiết
  • Xóa nhật ký nhị phân
  • Bỏ bàn cũ hoặc xây lại một cái bàn rất lớn

Xóa các tệp không cần thiết

Đây thường là bước đầu tiên cần thực hiện nếu máy chủ MySQL gặp sự cố hoặc không phản hồi hoặc bạn chưa bật nhật ký nhị phân. Ví dụ:các tệp trong / var / log / thường là nơi đầu tiên để tìm kiếm các tệp không cần thiết:

$ cd /var/log
$ find . -type f -size +5M -exec du -sh {} +
8.1M ./audit/audit.log.6
8.1M ./audit/audit.log.5
8.1M ./audit/audit.log.4
8.1M ./audit/audit.log.3
8.1M ./audit/audit.log.2
8.1M ./audit/audit.log.1
11M ./audit/audit.log
8.5M ./secure-20190429
8.0M ./wtmp

Ví dụ trên cho thấy cách truy xuất các tệp lớn hơn 5MB. Chúng tôi có thể xóa một cách an toàn các tệp nhật ký đã xoay thường ở định dạng {filename}. {Number}, chẳng hạn như từ Audit.log.1 cho đến Audit.log.6. Điều tương tự cũng có thể nói về bất kỳ bản sao lưu cũ khổng lồ nào được lưu trữ trong máy chủ. Nếu bạn đã thực hiện khôi phục thông qua Percona Xtrabackup hoặc MariaDB Backup, tất cả các tệp có tiền tố xtrabackup_ có thể bị xóa khỏi MySQL datadir, vì chúng không còn cần thiết để khôi phục. Tệp xtrabackup_logfile thường là tệp lớn nhất vì nó chứa tất cả các giao dịch được thực thi trong khi quá trình xtrabackup sao chép datadir đến đích. Ví dụ sau đây hiển thị tất cả các tệp liên quan trong MySQL datadir:

$ ls -lah /var/lib/mysql | grep xtrabackup_
-rw-r-----.  1 mysql root   286 Feb 4 11:30 xtrabackup_binlog_info
-rw-r--r--.  1 mysql root    24 Feb 4 11:31 xtrabackup_binlog_pos_innodb
-rw-r-----.  1 mysql root    83 Feb 4 11:31 xtrabackup_checkpoints
-rw-r-----.  1 mysql root   808 Feb 4 11:30 xtrabackup_info
-rw-r-----.  1 mysql root  179M Feb 4 11:31 xtrabackup_logfile
-rw-r--r--.  1 mysql root     1 Feb 4 11:31 xtrabackup_master_key_id
-rw-r-----.  1 mysql root   248 Feb 4 11:31 xtrabackup_tablespaces

Do đó, các tệp được đề cập là an toàn để bị xóa. Bắt đầu dịch vụ MySQL khi có thêm ít nhất 10% dung lượng trống.

Xóa Nhật ký Nhị phân

Nếu máy chủ MySQL vẫn đáp ứng và đã bật nhật ký nhị phân, ví dụ:để sao chép hoặc khôi phục tại thời điểm, chúng tôi có thể xóa các tệp nhật ký nhị phân cũ bằng cách sử dụng câu lệnh PURGE và cung cấp khoảng thời gian. Trong ví dụ này, chúng tôi đang xóa tất cả nhật ký nhị phân trước 3 ngày trước:

mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);
mysql> SHOW BINARY LOGS;

Đối với MySQL Replication, thật an toàn khi xóa tất cả các bản ghi đã được sao chép và áp dụng trên các nô lệ. Kiểm tra giá trị Relay_Master_Log_File trên máy chủ:

mysql> SHOW SLAVE STATUS\G
...
        Relay_Master_Log_File: binlog.000008
...

Và xóa các tệp nhật ký cũ hơn, ví dụ binlog.000007 trở lên. Bạn nên khởi động lại máy chủ MySQL để đảm bảo rằng nó có đủ tài nguyên. Chúng tôi cũng có thể để cho việc xoay vòng nhật ký nhị phân diễn ra tự động thông qua biến expire_logs_days (

mysql> SET GLOBAL expire_logs_days = 3;

Sau đó, thêm dòng sau vào tệp cấu hình MySQL trong phần [mysqld]:

expire_logs_days=3

Trong MySQL 8.0, hãy sử dụng binlog_expire_logs_seconds để thay thế, trong đó giá trị mặc định là 2592000 giây (30 ngày). Trong ví dụ này, chúng tôi giảm xuống chỉ còn 3 ngày (60 giây x 60 phút x 24 giờ x 3 ngày):

mysql> SET GLOBAL binlog_expire_logs_seconds = (60*60*24*3);
mysql> SET PERSIST binlog_expire_logs_seconds = (60*60*24*3);

SET PERSIST sẽ đảm bảo cấu hình được tải trong lần khởi động lại tiếp theo. Cấu hình được đặt bởi lệnh này được lưu trữ bên trong /var/lib/mysql/mysqld-auto.cnf.

Bỏ bảng cũ / tạo lại bảng

Lưu ý rằng thao tác XÓA sẽ không giải phóng dung lượng ổ đĩa trừ khi BẢNG TỐI ƯU HÓA được thực thi sau đó. Do đó, nếu bạn đã xóa nhiều hàng và bạn muốn trả lại dung lượng trống cho HĐH sau một thao tác DELETE lớn, hãy chạy BẢNG TỐI ƯU HÓA hoặc xây dựng lại nó. Ví dụ:

mysql> DELETE tbl_name WHERE id < 100000; -- remove 100K rows
mysql> OPTIMIZE TABLE tbl_name;

Chúng tôi cũng có thể buộc tạo lại bảng bằng cách sử dụng câu lệnh ALTER:

mysql> ALTER TABLE tbl_name FORCE;
mysql> ALTER TABLE tbl_name; -- a.k.a "null" rebuild

Lưu ý rằng hoạt động DDL ở trên được thực hiện thông qua DDL trực tuyến, có nghĩa là MySQL cho phép các hoạt động DML đồng thời trong khi quá trình xây dựng lại đang diễn ra. Một cách khác để thực hiện thao tác chống phân mảnh là sử dụng mysqldump để kết xuất bảng vào tệp văn bản, thả bảng và tải lại từ tệp kết xuất. Cuối cùng, chúng ta cũng có thể sử dụng DROP TABLE để xóa bảng không sử dụng hoặc BẢNG TRUNCATE để xóa tất cả các hàng trong bảng, do đó trả lại không gian cho HĐH.

Giải pháp vĩnh viễn cho các vấn đề về dung lượng đĩa

Tất nhiên, giải pháp lâu dài là thêm nhiều dung lượng hơn vào đĩa hoặc phân vùng tương ứng hoặc áp dụng quy tắc lưu giữ ngắn hơn để giữ các tệp không cần thiết trong máy chủ. Nếu bạn đang chạy trên hệ thống lưu trữ tệp có thể mở rộng, bạn sẽ có thể mở rộng quy mô tài nguyên mà không gặp quá nhiều rắc rối hoặc với sự gián đoạn và thời gian ngừng hoạt động tối thiểu đối với dịch vụ MySQL. Để tìm hiểu thêm về cách kích thước bộ nhớ của bạn và hiểu lập kế hoạch dung lượng MySQL và MariaDB, hãy xem bài đăng trên blog này.

Tóm tắt

Các vấn đề liên quan đến cơ sở dữ liệu liên quan đến đĩa là một trong những vấn đề phổ biến nhất liên quan đến quản trị viên cơ sở dữ liệu MySQL và nhà phát triển làm việc với RDBMS - tuy nhiên, trong khi những vấn đề đó có thể phổ biến, cũng có rất nhiều cách để giải quyết - và giải quyết chúng một cách tốt đẹp. Các cách giải quyết vấn đề như vậy có thể không phải lúc nào cũng đơn giản, tuy nhiên, tất cả chúng đều có thể được giải quyết với một chút nỗ lực và sự trợ giúp được cung cấp bởi các công cụ như ClusterControl.

Với khả năng giám sát chủ động của ClusterControl, bạn sẽ ít phải lo lắng nhất về các vấn đề liên quan đến cơ sở dữ liệu:bạn sẽ nhận được thông báo dưới dạng cảnh báo khi dung lượng ổ đĩa đã đạt đến 80% và thông báo dưới dạng cảnh báo quan trọng nếu sử dụng đĩa đạt 90% trở lên. Chúng tôi hy vọng rằng bài đăng trên blog này đã giúp bạn giải quyết được ít nhất một vài vấn đề liên quan đến việc sử dụng dung lượng đĩa MySQL, tận hưởng việc sử dụng ClusterControl của bạn và chúng tôi sẽ gặp bạn trong blog tiếp theo.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Khám phá các cách khác nhau để mã hóa dữ liệu MariaDB của bạn

  2. Cách hoạt động của SUBSTRING_INDEX () trong MariaDB

  3. Cách KHÔNG THÍCH hoạt động trong MariaDB

  4. MariaDB JSON_TYPE () Giải thích

  5. Cách ORD () hoạt động trong MariaDB