Bug #118093 Huge memory usage when inserting into a FTS table with a single transaction.
Submitted: 30 Apr 7:13 Modified: 30 Apr 16:44
Reporter: Huaxiong Song (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: FULLTEXT search Severity:S2 (Serious)
Version:8.0.42 OS:Any
Assigned to: CPU Architecture:Any

[30 Apr 7:13] Huaxiong Song
Description:
As the title states, when inserting a lot of data into a table containing FTS in a single transaction, a lot of memory consumption will be generated.

How to repeat:
# ======================Step 0=========================== #
# Start MySQL server with default configuration.
# ====================================================== #

# ======================Step 1========================== #
# Create a table with millions of rows, I use sysbench here.
CREATE DATABASE sbtest;
# Run sysbench to generate data to sbtest1 table.
sysbench oltp_read_write --mysql-host=$HOST --mysql-port=$PORT --mysql-user=$USER --mysql-password=$PASSWORD --tables=1 --threads=1 --table_size=4000000 --mysql-db=sbtest prepare

# the table structure is as follows:
```
CREATE TABLE `sbtest1` (
  `id` int NOT NULL AUTO_INCREMENT,
  `k` int NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=4000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
```
# ====================================================== #

# =======================Step 2========================= #
# Create FTS table and insert data to FTS table using 'INSERT INTO ... SELECT ...'
CREATE TABLE `t_fts` (
  `id` int NOT NULL,
  `c` char(120) NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `idx_c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO t_fts (id, c) SELECT id, c FROM sbtest1;
# ====================================================== #

# =======================Step 3========================= #
# Check the memory usage. In my tests, I found that the peak RSS can reach 10.4GB!
It seems that parameters innodb_ft_cache_size and innodb_ft_total_cache_size do not limit the memory, and sometimes the accumulated memory cannot be released in time.
# ====================================================== #

Suggested fix:
I introduced jemalloc to analyze the memory and found that the memory was mainly consumed in two aspects:
1. Insert:  rbt_add_node->ut::malloc_withkey 
2. Commit:  ib_vector_create->ib_heap_malloc

Maybe some memory can be freed early. :)
[30 Apr 7:14] Huaxiong Song
jemalloc result

Attachment: mem.pdf (application/pdf, text), 19.57 KiB.

[30 Apr 7:24] Huaxiong Song
Add jemalloc SVG

Attachment: mem.svg (image/svg+xml, text), 77.41 KiB.

[30 Apr 16:44] MySQL Verification Team
Hello Huaxiong Song,

Thank you for the report and test case.
Verified as described.

regards,
Umesh
[30 Apr 18:06] Pranay Motupalli
Another version of FTS cache not honoring limits. Cross linking for reference.

https://bugs.mysql.com/bug.php?id=116272