feat: implement MariaDbOperationService and add optimized MariaDB configuration template
This commit is contained in:
@@ -7,13 +7,15 @@ character-set-server=utf8mb4
|
||||
collation-server=utf8mb4_unicode_ci
|
||||
log-error="{{LOG_FILE}}"
|
||||
|
||||
# Performance Optimizations
|
||||
# Performance & Scale Optimizations
|
||||
max_allowed_packet=1G
|
||||
innodb_buffer_pool_size=512M
|
||||
innodb_log_file_size=128M
|
||||
innodb_buffer_pool_size=1G
|
||||
innodb_log_file_size=256M
|
||||
innodb_flush_log_at_trx_commit=2
|
||||
innodb_doublewrite=0
|
||||
innodb_lock_wait_timeout=600
|
||||
innodb_strict_mode=0
|
||||
innodb_default_row_format=DYNAMIC
|
||||
|
||||
[client]
|
||||
port={{PORT}}
|
||||
|
||||
@@ -3,6 +3,7 @@ import path from 'path'
|
||||
import { spawn } from 'child_process'
|
||||
import decompress from 'decompress'
|
||||
import zlib from 'zlib'
|
||||
import { pipeline, PassThrough } from 'stream'
|
||||
|
||||
export interface MariaDbConfig {
|
||||
binPath: string
|
||||
@@ -130,7 +131,8 @@ export class MariaDbOperationService {
|
||||
`--host=${config.host}`,
|
||||
`--port=${config.port}`,
|
||||
`--user=${config.rootUser}`,
|
||||
`--database=${dbName}`
|
||||
`--database=${dbName}`,
|
||||
'--max_allowed_packet=1G'
|
||||
]
|
||||
|
||||
if (config.rootPass) {
|
||||
@@ -139,50 +141,48 @@ export class MariaDbOperationService {
|
||||
|
||||
onProgress?.(`Executing: "${mariaDbPath}" ${args.join(' ')} < "${sqlFilePath}"`)
|
||||
|
||||
const child = spawn(mariaDbPath, args, { windowsHide: true })
|
||||
const child = spawn(mariaDbPath, args, { windowsHide: true, stdio: ['pipe', 'pipe', 'pipe'] })
|
||||
|
||||
// Create a wrapper stream to prepend/append SQL commands
|
||||
const combinedStream = new PassThrough()
|
||||
|
||||
// Send optimization headers
|
||||
combinedStream.write('SET GLOBAL innodb_strict_mode = 0;\n')
|
||||
combinedStream.write('SET SESSION innodb_strict_mode = 0;\n')
|
||||
combinedStream.write('SET foreign_key_checks = 0;\n')
|
||||
combinedStream.write('SET unique_checks = 0;\n')
|
||||
combinedStream.write('SET autocommit = 0;\n')
|
||||
combinedStream.write('SET sql_log_bin = 0;\n')
|
||||
|
||||
// Pipe the file content to stdin
|
||||
const fileStream = fs.createReadStream(sqlFilePath)
|
||||
|
||||
// Performance optimizations
|
||||
child.stdin.write('SET foreign_key_checks = 0;\n')
|
||||
child.stdin.write('SET unique_checks = 0;\n')
|
||||
child.stdin.write('SET autocommit = 0;\n')
|
||||
child.stdin.write('SET sql_log_bin = 0;\n')
|
||||
|
||||
fileStream.on('error', (err) => {
|
||||
onProgress?.(`File read error: ${err.message}`)
|
||||
})
|
||||
|
||||
fileStream.on('data', (chunk) => {
|
||||
if (child.stdin.writable) {
|
||||
try {
|
||||
child.stdin.write(chunk)
|
||||
} catch (e: any) {
|
||||
if (e.code === 'EPIPE') {
|
||||
onProgress?.(`Warning: EPIPE error encountered. The child process may have closed the pipe early.`)
|
||||
// Use pipeline for robust error handling and backpressure
|
||||
pipeline(
|
||||
fileStream,
|
||||
combinedStream,
|
||||
child.stdin,
|
||||
(err) => {
|
||||
if (err) {
|
||||
if (err.code === 'EPIPE' || err.code === 'ECONNRESET') {
|
||||
onProgress?.(`Notice: Pipe closed early (${err.code}). This is often normal if MariaDB finished early.`)
|
||||
} else if (err.code === 'ENOBUFS') {
|
||||
onProgress?.(`Error: System buffer overflow (ENOBUFS). The file might be too large for current system limits.`)
|
||||
} else {
|
||||
throw e
|
||||
onProgress?.(`Stream error: ${err.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// When file ends, send footer
|
||||
fileStream.on('end', () => {
|
||||
if (child.stdin.writable) {
|
||||
child.stdin.write('\nCOMMIT;\n')
|
||||
child.stdin.write('SET foreign_key_checks = 1;\n')
|
||||
child.stdin.write('SET unique_checks = 1;\n')
|
||||
child.stdin.write('SET autocommit = 1;\n')
|
||||
child.stdin.end()
|
||||
}
|
||||
})
|
||||
|
||||
child.stdin.on('error', (err: any) => {
|
||||
if (err.code === 'EPIPE') {
|
||||
onProgress?.(`Notice: Broken pipe (EPIPE). This usually means MariaDB finished or aborted before we finished writing.`)
|
||||
} else {
|
||||
onProgress?.(`Stdin error: ${err.message}`)
|
||||
// Ensure we don't write to a closed stream
|
||||
if (!combinedStream.writableEnded) {
|
||||
combinedStream.write('\nCOMMIT;\n')
|
||||
combinedStream.write('SET foreign_key_checks = 1;\n')
|
||||
combinedStream.write('SET unique_checks = 1;\n')
|
||||
combinedStream.write('SET autocommit = 1;\n')
|
||||
combinedStream.end()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user