[MDEV-18525] mysql client runs out of memory on a box with 154G of free ram Created: 2019-02-09  Updated: 2019-03-11  Resolved: 2019-03-11

Status: Closed
Project: MariaDB Server
Component/s: Scripts & Clients
Affects Version/s: 10.3.12
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Philip orleans Assignee: Unassigned
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

ubuntu 18.04



 Description   

mysql asterisk -e "select * from npadata" > NAmDB.csv
ERROR 2008 (HY000) at line 1: MySQL client run out of memory
root@ubuntu:/usr/src# free -g
total used free shared buff/cache available
Mem: 307 145 153 0 8 160
Swap: 126 0 126



 Comments   
Comment by Elena Stepanova [ 2019-02-09 ]

Does it happen every time you run the query?
Does it always happen on the same table? If so, how big is the table? Can you paste the output of

SHOW CREATE TABLE npadata;
select * from information_schema.tables where table_schema='asterisk' and table_name='npadata' \G

?
Does it happen right away, or after a long time of query execution?
Does the client process actually grow that big before failing, or is it a bogus error?
Does it happen if you run SELECT with a LIMIT?

Comment by Philip orleans [ 2019-02-12 ]

It happens after like an hour
CREATE TABLE `npadata` (
`state` varchar(2) NOT NULL DEFAULT '??',
`company` varchar(30) DEFAULT NULL,
`ocn` varchar(4) NOT NULL DEFAULT 'N/A',
`prefix_type` varchar(10) DEFAULT NULL,
`ratecenter` varchar(40) DEFAULT NULL,
`clli` varchar(20) DEFAULT NULL,
`lata` varchar(5) DEFAULT NULL,
`country` varchar(2) DEFAULT NULL,
`wireless` tinyint(1) unsigned NOT NULL DEFAULT 0,
`did` bigint(20) unsigned NOT NULL,
`lrn` bigint(20) unsigned DEFAULT NULL,
`port_type` tinyint(4) unsigned DEFAULT NULL,
`dnc` tinyint(4) unsigned DEFAULT NULL,
`reachable` tinyint(4) unsigned DEFAULT NULL,
`npa` varchar(3) DEFAULT NULL,
`nxx` varchar(3) DEFAULT NULL,
`xxxx` varchar(4) DEFAULT NULL,
`tested` tinyint(1) DEFAULT 0,
`lastchange` date NOT NULL DEFAULT curdate(),
PRIMARY KEY (`did`),
KEY `IDX_npadata` (`wireless`,`ocn`,`company`),
KEY `IDX_npadata_state` (`state`,`wireless`,`country`),
KEY `IDX_npadata2` (`npa`,`nxx`),
KEY `IDX_npadata_lrn` (`lrn`),
KEY `IDX_npadata3` (`reachable`,`tested`),
KEY `IDX_npadata_COMPANY` (`company`,`wireless`),
KEY `IDX_npadata_dnc` (`dnc`),
KEY `IDX_npadata_lastchange` (`lastchange`),
KEY `IDX_npadata_tested` (`tested`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=49

The table as 1.97BN rows.
The tool should request as much memory as it needs from the OS, and never crash.

Comment by Sergei Golubchik [ 2019-02-12 ]

It doesn't seem to be crashing, it gracefully exits with an error "MySQL client run out of memory".

An easy workaround for you would be to use the mysql -q, it will print results as received, row by row, instead of trying to read the whole result set in memory first.

There might be something we can change in the client, but by far the fastest and easiest solution for you is to use -q option.

Comment by Elena Stepanova [ 2019-02-13 ]

But does it actually use all the memory before aborting with the error?
If yes, then it does exactly that – "requests as much memory as it needs from the OS", cannot get it and bails out. Then the advice above seems the only reasonable option.
If there is still a lot of free memory by the time it aborts, then maybe something else is wrong.

Comment by Philip orleans [ 2019-02-13 ]

The tool needs to be rewritten, instead of saving all the result set in memory, as noted earlier, it should write off a smaller buffer, and never request or use all the memory in the box. In any case, the parameter "-g" should be on by default. I would say that this a problem, a big problem. Why would anybody write a tool that behaves like this? It's a gross architectural misdesign.

Comment by Sergei Golubchik [ 2019-02-13 ]

See

$ mysql --help
...
  -q, --quick         Don't cache result, print it row by row. This may slow
                      down the server if the output is suspended. Doesn't use
                      history file.
...

So, the logic here is to read the result from the server and free the server for other tasks as soon as possible. Because normally the client has enough memory to read the whole result set, it's better to use it, instead of blocking the server while the client consumes rows one by one.

Generated at Thu Feb 08 08:44:47 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.