Skip to main content

High swap usage that goes away when restarting SQL

Comments

2 comments

  • cPRex Jurassic Moderator

    Hey there!  A few thoughts.

    With MySQL only running for about 36 hours, the tuner script may not always give the best advice.  Having the service up a bit longer typically lets it give better output, but I understand this may not be an option in your situation.

    it might be best to see what the database is doing in real time by running "mysqladmin proc status" on the machine.  This will show you all the connections and what they are doing, which might point you in the right direction if one particular site is busy or having an issue with the database.

    Ultimately, I don't think there is any particular cPanel issue here, but just something with the database handling your transactions specifically that is causing the problem.

    0
  • victor rege

    A few things stand out in your config and tuner output that point toward a specific culprit rather than a general "tune more RAM" fix:

    1. Buffer pool instances vs. size mismatch
    You have innodb_buffer_pool_size = 2000M split across 8 buffer pool instances. MySQL recommends roughly 1GB minimum per instance — at 2GB total split 8 ways, each instance is only ~250MB, which hurts efficiency and fragments memory unnecessarily. Either drop innodb_buffer_pool_instances to 1-2, or raise the pool size significantly if you go with 8.

    2. The real leak suspect: performance_schema
    Your performance-schema=ON is using 390MB and on a memory-constrained 8GB box with 15,600+ InnoDB tables and heavy table churn, performance_schema's internal memory tables can grow unpredictably over time — this fits your exact symptom (swap climbs gradually, resets on restart). Try setting performance-schema=OFF (or heavily limiting instrumentation) for a week and watch swap behavior. This is a very common cause of "slow memory creep that a restart fixes."

    3. MyISAM tables (7,944 of them!)
    MyISAM doesn't respect innodb_buffer_pool_size — it uses OS page cache and key_buffer_size instead. With that many MyISAM tables (likely old Joomla/WP installs or leftover cache tables), the OS is caching all that in page cache, competing with everything else for RAM and pushing things into swap under load spikes. Migrating them to InnoDB (as the tuner also suggested) would consolidate memory management under one engine.

    4. Table cache is very large
    table_open_cache=8000 and table_definition_cache=25000 — with ~24,000 total tables, this is reasonable, but combined with the above two issues, it adds sustained memory pressure that never gets released back to the OS (a well-known glibc/MySQL memory fragmentation issue, especially on high table-count servers with frequent connection churn — you have 832K connections in 36 hours).

    5. Quick diagnostic step
    Before changing anything else, run this during a high-swap period:

     
    cat /proc/$(pidof mysqld)/status | grep -i vm

    and compare VmRSS (actual resident memory) vs what free -m reports as used. If MySQL's own RSS is much lower than total swap usage, MySQL isn't the actual leak — something else (php-fpm, an unbounded process for a Joomla/WP site) is filling RAM and MySQL is just the collateral damage when it can't allocate anything fast, which is a very plausible alternative explanation for "restarting SQL fixes it" — restarting SQL frees several hundred MB instantly and buys headroom, even if it wasn't the actual leaking process.

    Suggested next steps in order:

    1. Run the mysqladmin proc status moderator suggested during a spike
    2. Turn off performance_schema temporarily and monitor
    3. Set up that memory-watch cron script and let it run through a swap-filling cycle so you can see what's actually growing minute by minute
    4. Check ps aux --sort=-%mem at the same time to rule out php-fpm/Apache/LiteSpeed workers as the real memory hog

    Happy to help interpret the memwatch log output once you've collected it.

    1

Please sign in to leave a comment.