MySQL OperationalError: 1317 Query execution was interrupted
Increase MAX_EXECUTION_TIME in MySQL or optimize slow queries using database indexes and query profiling (EXPLAIN).
Root Cause Analysis
This error occurs when a running SQL query executed by Python (via PyMySQL, mysqlclient, SQLAlchemy, or Django ORM) is terminated by the MySQL server before completion, returning MySQL error code 1317 (ER_QUERY_INTERRUPTED).
1. MySQL Server MAX_EXECUTION_TIME Thresholds
Modern MySQL (5.7+ and 8.0+) allows DBAs to enforce execution limits on read queries via SET SESSION MAX_EXECUTION_TIME = N (in milliseconds). When a heavy unindexed SELECT or table scan exceeds this threshold, MySQL kills the thread and raises error 1317.
2. Client-Side Socket Timeout Disconnections
If the Python client or connection pool (Gunicorn worker timeout, SQLAlchemy pool timeout) closes the TCP socket while the server is still executing, MySQL aborts execution.
3. DBA or Load Balancer KILL QUERY Commands
Database monitoring daemons (such as AWS RDS kill policies or ProxySQL) terminate queries causing high CPU load or lock contention.
4. Deadlock Victim Selection
Under intense transactional concurrency, MySQL's InnoDB engine may terminate queries involved in lock cycles.
Reproduction Code (MCVE)
# **Note de reproductibilité :** Dépendant de la charge de la base de données.
class OperationalError(Exception):
pass
raise OperationalError("(1317, 'Query execution was interrupted')")
Solution 1: Optimize Slow Queries and Add Database Indexes
Analyze slow queries with EXPLAIN to ensure proper indexing and prevent full table scans that trigger execution limits.
print('Database indexing best practice:')
print('ALTER TABLE orders ADD INDEX idx_created_user (user_id, created_at);')
print('Inspect query performance: EXPLAIN SELECT * FROM orders WHERE user_id = 123;')
Solution 2: Adjust Execution Timeout and Pool Connection Parameters
Configure appropriate query timeouts in SQLAlchemy or PyMySQL connection parameters.
print('SQLAlchemy connection string with execution options:')
print('engine = create_engine(')
print(' "mysql+pymysql://user:pass@localhost/dbname",')
print(' execution_options={"timeout": 60},')
print(' pool_recycle=3600,')
print(' pool_pre_ping=True')
print(')')
A common mistake is simply increasing timeouts without investigating why queries take 30+ seconds to execute. Increasing timeouts in high-traffic applications exhausts connection pools and degrades entire clusters. Always add appropriate B-Tree or composite indexes first. Edge cases occur during large batch updates: process data in paginated chunks of 1,000 records using WHERE id > last_id LIMIT 1000. Contrast this error with OperationalError: (2006, 'MySQL server has gone away'), which indicates socket disconnections due to max_allowed_packet or idle wait timeouts.