web-dev-qa-db-ja.com

MySQLで正しいinnodb_log_file_sizeを設定する

今日、DBを停止する代替テーブルを実行しました。私たちはスレーブにフェイルオーバーし、死後、mysqlでこれを発見しましたerror.log

InnoDB: ERROR: the age of the last checkpoint is 90608129,
InnoDB: which exceeds the log group capacity 90593280.
InnoDB: If you are using big BLOB or TEXT rows, you must set the
InnoDB: combined size of log files at least 10 times bigger than the
InnoDB: largest such row.

BLOBデータ型を含む非常に大きなテーブルで作業していたため、このエラーは真実です。

最良の回答 オンラインで見つけた

それを解決するには、MySQLを完全に停止し(非常に重要)、既存のInnoDBログファイル(おそらく、移動していない限り、MySQLデータディレクトリのlb_logfile *)を削除し、必要に応じてinnodb_log_file_sizeを調整してから、 MySQLを再起動します。 MySQLパフォーマンスブログのこの記事は参考になるかもしれません。

そしてコメントで

はい、データベースサーバーは、ログがいっぱいになると、InnoDBテーブルへの更新があると事実上ハングします。それはサイトを不自由にすることができます。

48mbの現在の(デフォルト)innodb_log_file_sizeに基づいて、何が起こったと思いますか?

SHOW GLOBAL VARIABLES LIKE '%innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 8388608  |
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
+-----------------------------+----------+

だから、これは私に2つの指摘された質問と1つの自由回答式の質問につながります:

  1. innodb_log_file_sizeをそれより大きく設定できるように、最大​​の行をどのように決定しますか?
  2. ステップ1のアクションの結果は何ですか?ログが大きくなると、回復時間が長くなることを読んだ。
  3. 制限のない可変長のBLOBフィールドを持つ大きなテーブル(650k行、6169.8GB)があることを考えると、移行に関して他に注意すべきことはありますか?.

Mysql 5.6を実行しています。ここにmy.cnfがあります。

[mysqld]

#defaults
basedir                   = /opt/mysql/server-5.6
datadir                   = /var/lib/mysql
port                      = 3306
socket                    = /var/run/mysqld/mysqld.sock
tmpdir                    = /tmp
bind-address              = 0.0.0.0

#logs
log_error                 = /var/log/mysql/error.log
expire_logs_days          = 4
slow_query_log            = on
long_query_time           = 1


innodb_buffer_pool_size   = 11G

#http://stackoverflow.com/a/10866836/182484
collation-server          = utf8_bin
init-connect              ='SET NAMES utf8'
init_connect              ='SET collation_connection = utf8_bin'
character-set-server      = utf8
max_allowed_packet        = 64M
skip-character-set-client-handshake

#cache
query_cache_size          = 268435456
query_cache_type          = 1
query_cache_limit         = 1048576
```

以下の提案のフォローアップとして、問題のテーブルのファイルサイズの調査を開始しました。 3つのBLOBフィールドの合計バイトサイズをpen_sizesというテーブルに書き込むスクリプトを実行しました。最大のバイトサイズを取得した結果は次のとおりです。

select pen_size as bytes,·
  pen_size  /  1024 / 1024 as mb,·
  pen_id from pen_sizes
  group by pen_id
  order by bytes desc
  limit 40

+---------+------------+--------+
| bytes   | mb         | pen_id |
+---------+------------+--------+
| 3542620 | 3.37850571 |  84816 |
| 3379107 | 3.22256756 |  74796 |
| 3019237 | 2.87936878 | 569726 |
| 3019237 | 2.87936878 | 576506 |
| 3019237 | 2.87936878 | 576507 |
| 2703177 | 2.57795048 | 346965 |
| 2703177 | 2.57795048 | 346964 |
| 2703177 | 2.57795048 |  93706 |
| 2064807 | 1.96915340 | 154627 |
| 2048592 | 1.95368958 | 237514 |
| 2000695 | 1.90801144 |  46798 |
| 1843034 | 1.75765419 | 231988 |
| 1843024 | 1.75764465 | 230423 |
| 1820514 | 1.73617744 |  76745 |
| 1795494 | 1.71231651 | 650208 |
| 1785353 | 1.70264530 |  74912 |
| 1754059 | 1.67280102 | 444932 |
| 1752609 | 1.67141819 |  76607 |
| 1711492 | 1.63220596 | 224574 |
| 1632405 | 1.55678272 |  76188 |
| 1500157 | 1.43066120 |  77256 |
| 1494572 | 1.42533493 | 137184 |
| 1478692 | 1.41019058 | 238547 |
| 1456973 | 1.38947773 | 181379 |
| 1433240 | 1.36684418 |  77631 |
| 1421452 | 1.35560226 | 102930 |
| 1383872 | 1.31976318 |  77627 |
| 1359317 | 1.29634571 | 454109 |
| 1355701 | 1.29289722 | 631811 |
| 1343621 | 1.28137684 |  75256 |
| 1343621 | 1.28137684 |  75257 |
| 1334071 | 1.27226925 |  77626 |
| 1327063 | 1.26558590 | 129731 |
| 1320627 | 1.25944805 | 636914 |
| 1231918 | 1.17484856 | 117269 |
| 1223975 | 1.16727352 |  75103 |
| 1220233 | 1.16370487 | 326462 |
| 1220233 | 1.16370487 | 326463 |
| 1203432 | 1.14768219 | 183967 |
| 1200373 | 1.14476490 | 420360 |
+---------+------------+--------+

これにより、平均行サイズは推奨される10よりも1 MBに近いと思います。たぶん、前に挙げたテーブルサイズにインデックスも含まれているのでしょうか。

私は走った

SELECT table_name AS "Tables", 
round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" 
FROM information_schema.TABLES 
WHERE table_schema = 'codepen'

+-------------------+------------+
| Tables            | Size in MB |
+-------------------+------------+
...snip
| pens              |    6287.89 |
...snip
12
timsabat

0。予備情報

あなたの設定:

innodb_log_file_size = 50331648
innodb_log_files_in_group = 2

したがって、「 ロググループ容量 = 2 x 50331648 = 96 MB

1。最大の行を特定する方法

直接的な方法はありません。しかし、1つの行のサイズを簡単に計算できます これらのテーブルに基づいて (私が想定しているように、ログファイルで行が圧縮されていない場合、ここでは圧縮は問題になりません)。

2。 innodb_log_file_sizeの影響

リファレンスマニュアル

値が大きいほど、バッファープールで必要なチェックポイントフラッシュアクティビティが少なくなり、ディスクI/Oが節約されます。ログファイルのサイズが大きいと、クラッシュリカバリが遅くなりますが、MySQL 5.5以降でのリカバリパフォーマンスの向上により、ログファイルのサイズを考慮する必要が少なくなります。

3。他に気にすること

6169.8 GB/650k行=平均で行あたり約10 MBこれは、トランザクション、マルチユーザーの状況でデータベースを使用する場合、それ自体が深刻な問題です。 BLOBをデータベース外のファイルとして保存することを検討してください。または、少なくとも、それらを別のMyISAM(非トランザクション)テーブルに格納します。

9
RandomSeed