TABLE STATUSによると7MMの行を持つデータベーステーブルがありますが、SELECT COUNT(*)を実行すると500k行しかありません。
テーブルの増加が増加しており、現在ストレージが不足しているため、これは問題です。
これがスキーマです:MySQL 8.0.15
CREATE TABLE `tasks` (
`task_id` binary(24) NOT NULL,
`task` json NOT NULL,
`task_kryo` mediumblob,
`task_type` varchar(180) COLLATE utf8_bin GENERATED ALWAYS AS (json_unquote(json_extract(`task`,_utf8mb4'$.t'))) STORED,
`created` datetime GENERATED ALWAYS AS (cast(left(json_unquote(json_extract(`task`,_utf8mb4'$._task.timestamp')),19) as datetime)) STORED,
`last_updated` datetime GENERATED ALWAYS AS (cast(left(json_unquote(json_extract(`task`,_utf8mb4'$._task.latestStatus.timestamp')),19) as datetime)) STORED,
`latest_status` varchar(180) COLLATE utf8_bin GENERATED ALWAYS AS (json_unquote(json_extract(`task`,_utf8mb4'$._task.latestStatus.t'))) STORED,
`marker` binary(24) GENERATED ALWAYS AS (json_unquote(json_extract(`task`,_utf8mb4'$.marker'))) STORED,
PRIMARY KEY (`task_id`),
KEY `task_type_index` (`task_type`),
KEY `created_index` (`created`),
KEY `last_updated_index` (`last_updated`),
KEY `latest_status_index` (`latest_status`),
KEY `marker_index` (`marker`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
これは、AWS上のMySQL RDSです。このテーブルは完全に使い捨てデータであるため、システムバックアップは無効になっています。その結果、このテーブルのバイナリログはありません。 AWSは、システムバックアップを無効にすると明らかに無効になります
私の疑いは、UpdateステートメントでJSON "Merge"操作を使用していることと、バイナリログがAWSによって無効になっているためです(このテーブルは完全に使い捨て/スクラッチデータであるため、このテーブルのバックアップはありません)。テーブルへの挿入(古いレコードは残りますが、削除されません)。
参照 https://mysqlhighavailability.com/efficient-json-replication-in-mysql-8-0/
binlog-row-value-options = PARTIAL_JSON
また、MySQLログには再起動時に次の警告が含まれます。
2020-05-21T20:02:08.506526Z 0 [Warning] [MY-013103] [Server] When binlog_row_image=FULL, the option binlog_row_value_options=PARTIAL_JSON will be used only for the after-image. Full values will be written in the before-image, so the saving in disk space due to binlog_row_value_options is limited to less than 50%.
これはInnoDBとさらに関係があります
documentation で述べたように、テーブルのステータス
行の数。 MyISAMなどの一部のストレージエンジンは、正確な数を保存します。 InnoDBなどの他のストレージエンジンの場合、この値は概算値であり、実際の値と40%〜50%程度異なる場合があります。そのような場合は、SELECT COUNT(*)を使用して正確なカウントを取得してください。
したがって、COUNT(*)は正確な数を示します。
_analyze table tasks;
_を使用して更新された統計を収集し、_show table status
_がselect count(*) from tasks
の値を反映しているかどうかを確認してください。 select count(*)
は常に正確な値を返す必要がありますが、テーブル統計(_show table status
_に表示)は最新ではない可能性があります。