Skip to content

Commit d47bd18

Browse files
authored
Merge pull request #37 from marshmallow-packages/36-the-process-mysql--h-127001--u-root--p-example_database-downloadsnew_datasql-exceeded-the-timeout-of-60-seconds
(feature) Add configurable process timeout for database sync
2 parents c87e693 + 5af2971 commit d47bd18

13 files changed

Lines changed: 176 additions & 8 deletions

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ A powerful Laravel package that enables seamless synchronization of data from a
1313
- [Advanced Options](#advanced-options)
1414
- [Per-Table Sync Tracking](#per-table-sync-tracking)
1515
- [Table Configuration](#table-configuration)
16+
- [Timeout Configuration](#timeout-configuration)
1617
- [Synchronization Suites](#synchronization-suites)
1718
- [Multi-Tenant Support](#multi-tenant-support)
1819
- [Testing](#testing)
@@ -168,6 +169,30 @@ You can exclude specific tables from synchronization in the `config/database-syn
168169
],
169170
```
170171

172+
### Timeout Configuration
173+
174+
For large databases, you may need to adjust the process timeout to prevent operations from timing out:
175+
176+
```php
177+
// Set timeout in seconds (default: 300 seconds / 5 minutes)
178+
'process_timeout' => 600, // 10 minutes
179+
180+
// Or set to null to disable timeout entirely for very large databases
181+
'process_timeout' => null,
182+
```
183+
184+
You can also set this via environment variable:
185+
186+
```env
187+
DATABASE_SYNC_PROCESS_TIMEOUT=600
188+
```
189+
190+
This timeout applies to:
191+
192+
- MySQL dump operations (`mysqldump`)
193+
- MySQL import operations (`mysql`)
194+
- File transfer operations (`scp`)
195+
171196
### Synchronization Suites
172197

173198
Define custom synchronization suites in the configuration file to group tables for specific sync tasks:

config/database-sync.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,17 @@
119119
'mysql' => [
120120
'dump_action_flags' => '--skip-lock-tables --no-create-info --complete-insert --skip-triggers --replace',
121121
],
122+
123+
/*
124+
|--------------------------------------------------------------------------
125+
| Process Timeout Configuration
126+
|--------------------------------------------------------------------------
127+
|
128+
| Set the timeout (in seconds) for long-running database operations.
129+
| Set to null to disable timeout entirely for very large databases.
130+
| Default: 300 seconds (5 minutes)
131+
|
132+
*/
133+
134+
'process_timeout' => env('DATABASE_SYNC_PROCESS_TIMEOUT', 300),
122135
];
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Troubleshooting Large Database Sync Issues
2+
3+
## Timeout Errors
4+
5+
If you encounter timeout errors like:
6+
7+
```
8+
The process "mysql -h 127.0.0.1 -u root -p'***' example_database < ~/Downloads/new_data.sql" exceeded the timeout of 60 seconds.
9+
```
10+
11+
### Solution
12+
13+
Configure the `process_timeout` setting in your `config/database-sync.php` file:
14+
15+
```php
16+
// Set timeout in seconds (default: 300 seconds / 5 minutes)
17+
'process_timeout' => 600, // 10 minutes
18+
19+
// Or set to null to disable timeout entirely for very large databases
20+
'process_timeout' => null,
21+
```
22+
23+
Or set via environment variable:
24+
25+
```env
26+
DATABASE_SYNC_PROCESS_TIMEOUT=600
27+
```
28+
29+
### Affected Operations
30+
31+
The timeout setting applies to:
32+
33+
- MySQL dump operations (`mysqldump`)
34+
- MySQL import operations (`mysql`)
35+
- File transfer operations (`scp`)
36+
- Remote file operations (`ssh rm`)
37+
38+
### Recommendations by Database Size
39+
40+
- **Small databases (< 100MB)**: Default timeout (300 seconds) should be sufficient
41+
- **Medium databases (100MB - 1GB)**: Set timeout to 600-1800 seconds (10-30 minutes)
42+
- **Large databases (> 1GB)**: Consider setting timeout to `null` to disable it entirely
43+
44+
### Alternative Solutions
45+
46+
1. **Use batch transfer mode**: This is enabled by default and combines all table dumps into a single file transfer, which is more efficient for large databases.
47+
48+
2. **Sync specific tables**: Use the `--table` option to sync only specific tables:
49+
50+
```bash
51+
php artisan db-sync --table=users
52+
```
53+
54+
3. **Use suites**: Group related tables and sync them separately:
55+
56+
```bash
57+
php artisan db-sync --suite=orders
58+
```
59+
60+
4. **Increase MySQL timeouts**: You may also need to adjust MySQL server timeouts:
61+
```sql
62+
SET global net_read_timeout=600;
63+
SET global net_write_timeout=600;
64+
```
65+
66+
## Memory Issues
67+
68+
For very large datasets, you may need to adjust PHP memory limits:
69+
70+
```bash
71+
php -d memory_limit=512M artisan db-sync
72+
```
73+
74+
## Network Issues
75+
76+
If you experience network-related timeouts during file transfers:
77+
78+
1. Ensure stable SSH connection to remote server
79+
2. Consider using compression in SSH config
80+
3. Check available disk space on both local and remote systems
81+
4. Verify network bandwidth between servers

src/Actions/CopyRemoteFileToLocalAction.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ public static function handle(
1919
$command->info(__('Copying file to local machine...'));
2020
}
2121
$copyCommand = "scp {$config->remote_user_and_host}:{$config->remote_temporary_file} {$config->local_temporary_file}";
22-
$result = Process::run($copyCommand);
22+
23+
$process = Process::timeout($config->process_timeout);
24+
$result = $process->run($copyCommand);
2325

2426
if ($result->failed()) {
2527
throw new \Exception(__('Failed to copy remote file to local: :error', ['error' => $result->errorOutput()]));

src/Actions/Mysql/DumpCreatedOrUpdatedDataAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static function handle(
2626
]));
2727
}
2828

29-
Process::run($exportCommand)->output();
29+
$process = Process::timeout($config->process_timeout);
30+
$process->run($exportCommand)->output();
3031
}
3132
}

src/Actions/Mysql/DumpDeletedDataAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public static function handle(
3131
]));
3232
}
3333

34-
Process::run($exportCommand)->output();
34+
$process = Process::timeout($config->process_timeout);
35+
$process->run($exportCommand)->output();
3536
}
3637
}

src/Actions/Mysql/DumpFullTableDataAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static function handle(
2626
]));
2727
}
2828

29-
Process::run($exportCommand)->output();
29+
$process = Process::timeout($config->process_timeout);
30+
$process->run($exportCommand)->output();
3031
}
3132
}

src/Actions/Mysql/ImportDataAction.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ public static function handle(
1818
}
1919

2020
$importCommand = "mysql -h {$config->local_host} -u {$config->local_database_username} -p'{$config->local_database_password}' {$config->local_database} < {$config->local_temporary_file}";
21-
$result = Process::run($importCommand);
21+
22+
$process = Process::timeout($config->process_timeout);
23+
$result = $process->run($importCommand);
2224

2325
if ($result->failed()) {
2426
throw new \Exception(__('Failed to import data to local database: :error', ['error' => $result->errorOutput()]));

src/Actions/RemoveLocalFileAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static function handle(
1313
/**
1414
* Delete the local SQL dump file
1515
*/
16-
Process::run("rm -f {$config->local_temporary_file}");
16+
$process = Process::timeout($config->process_timeout);
17+
$process->run("rm -f {$config->local_temporary_file}");
1718
}
1819
}

src/Actions/RemoveRemoteFileAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static function handle(
1313
/**
1414
* Delete the remote SQL dump file
1515
*/
16-
Process::run("ssh {$config->remote_user_and_host} 'rm -f {$config->remote_temporary_file}'");
16+
$process = Process::timeout($config->process_timeout);
17+
$process->run("ssh {$config->remote_user_and_host} 'rm -f {$config->remote_temporary_file}'");
1718
}
1819
}

0 commit comments

Comments
 (0)