I know this error is infuriating. Your Cloud SQL instance churns, restarts, then does it again. You can't connect, your app is down, and you're staring at a loop that won't stop.
Here's the fix: The most common reason is the database ran out of memory. MySQL 8.0 eats RAM like candy if you don't set limits. The database tries to grow, hits the wall, crashes, restarts, and repeats.
Step 1: Check the logs
Before changing anything, confirm the problem. Go to Cloud Logging in GCP Console. Filter for your Cloud SQL instance. Look for messages like:
"Out of memory"
"Killed"
"Buffer pool size"
If you see these, you're in the right place.
Step 2: Reduce the innodb_buffer_pool_size
This setting controls how much memory MySQL uses for caching. Default is 75% of available RAM. That's too much for small instances. On a 1GB instance, that leaves almost nothing for the OS or queries.
Set it lower. Here's the SQL command:
SET GLOBAL innodb_buffer_pool_size = 268435456;
That's 256MB. But this change won't survive a restart. You need to make it permanent.
Step 3: Add a database flag
In Cloud SQL, you set flags in the Console or using gcloud. The flag name is innodb_buffer_pool_size. Value is bytes. For a 2GB instance, use 536870912 (512MB). For 1GB, use 268435456 (256MB).
Applying the flag will restart the instance. That's fine — it's a controlled restart, not the crash loop.
Why this works
MySQL 8.0 pre-allocates the buffer pool on startup. If you set it too high, the OS can't allocate that memory. The kernel kills the MySQL process. Cloud SQL detects the crash, restarts it, and the same thing happens again. It's a death spiral.
I've seen this on GCP's e2-medium instances (2GB RAM) with default settings. The fix is always the same: shrink the buffer pool.
Less common variations
If reducing the buffer pool didn't work, check these:
- Temporary table size:
tmp_table_sizeandmax_heap_table_sizedefault to 16MB. If you have big temp tables, they can eat memory. Set them to 32MB each. - Thread cache:
thread_cache_sizedefault is 8. If you have many connections, increase to 100. Each thread uses some memory. - Query cache: Query cache is deprecated in MySQL 8.0. Make sure it's off. If on, it wastes memory.
- Connection pooling: Too many connections? Limit max_connections to 100 or less. Each connection uses about 256KB.
Prevention tips
You can avoid this mess next time:
- Monitor memory usage with Cloud Monitoring. Set an alert when memory hits 80%.
- Start with a smaller buffer pool. Increase it slowly, monitoring each time.
- Use a larger instance if your database is big. Don't force a 500MB database into a 1GB instance.
- Set all memory flags before you start loading data. It's easier to fix upfront.
One trick I use: When you create a new Cloud SQL instance, set innodb_buffer_pool_size to 50% of RAM. Then adjust later if needed. That saved me from this loop more than once.
That's it. Your instance should stay up now. If it doesn't, check the logs again — maybe it's a storage issue or a corrupted table. But 9 times out of 10, it's memory.