Skip to content

Commit a8b0093

Browse files
authored
perf: retry dump audit table on failed (#11)
Change-Id: I7c27edf083cc1cc33649432fed922e3ebad6b72c
1 parent 0202c24 commit a8b0093

File tree

8 files changed

+76
-70
lines changed

8 files changed

+76
-70
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ build-linux:
2020
run:
2121
@go run main.go $(ARGS)
2222

23+
test:
24+
@go test -v ./...
25+
2326
install: build
2427
cp dorisdump /usr/local/bin
2528

README.md

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,8 @@ dorisdump dump --dump-schema --host <host> --port <port> --user root --password
2525
# Hint: Use '*' like '/path/to/fe.audit.log*' to match multiple logs
2626
dorisdump dump --dump-schema --dump-query --dbs db1 --audit-logs '/path/to/fe.audit.log,/path/to/fe.audit.log.20240802-1'
2727

28-
# Auto download audit log from remote FE (require SSH password or private key)
29-
dorisdump dump --dump-query --host <fe host> --port <fe port> --ssh-password '******'
30-
31-
# Dump queries from audit log table instead of files
32-
# Need to enable audit plugin on FE, see <https://doris.apache.org/docs/admin-manual/audit-plugin>
33-
dorisdump dump --dump-query --host <fe host> --port <fe port> --audit-log-table=audit_db.audit_table
28+
# Dump queries from audit log table instead of files, need enable <https://doris.apache.org/docs/admin-manual/audit-plugin>
29+
dorisdump dump --dump-query --audit-log-table <db.table> --from '2024-11-14 18:45:25' --to '2024-11-14 18:45:26'
3430

3531

3632
# Replay

fixture/q0.sql

+12-12
Large diffs are not rendered by default.

fixture/replay.sql

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
/*dorisdump{"ts":"2024-08-06 23:44:11,041","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"8cb2e4f433e74463-a0ededde7b648b35"}*/ select "hello world 1" as hello;
2-
/*dorisdump{"ts":"2024-08-06 23:44:11,043","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"8eaf2c126a249c7-8d48a95bd8501cc9"}*/ select 1.0 as num;
3-
/*dorisdump{"ts":"2024-08-06 23:44:12,044","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"60b885f02d014194-b225555e4ed26d7e"}*/ select 'hello world 2' as hello;
4-
/*dorisdump{"ts":"2024-08-06 23:44:11,045","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"ffb1d743a9eb4394-9b48a38bcc0b8b19"}*/ select 2.0 as num;
5-
/*dorisdump{"ts":"2024-08-06 23:44:13,046","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"41dc7120df0040c0-a677b93ad1a28d27"}*/ select "hello world 3" as hello;
6-
/*dorisdump{"ts":"2024-08-06 23:44:12,047","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"18799575029447f9-a6a3fc65c8eda3f1"}*/ SHOW VARIABLES LIKE
1+
/*dorisdump{"ts":"2024-08-06 23:44:11.041","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"8cb2e4f433e74463-a0ededde7b648b35"}*/ select "hello world 1" as hello;
2+
/*dorisdump{"ts":"2024-08-06 23:44:11.043","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"8eaf2c126a249c7-8d48a95bd8501cc9"}*/ select 1.0 as num;
3+
/*dorisdump{"ts":"2024-08-06 23:44:12.044","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"60b885f02d014194-b225555e4ed26d7e"}*/ select 'hello world 2' as hello;
4+
/*dorisdump{"ts":"2024-08-06 23:44:11.045","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"ffb1d743a9eb4394-9b48a38bcc0b8b19"}*/ select 2.0 as num;
5+
/*dorisdump{"ts":"2024-08-06 23:44:13.046","client":"192.168.48.119:51970","user":"root","db":"__internal_schema","queryId":"41dc7120df0040c0-a677b93ad1a28d27"}*/ select "hello world 3" as hello;
6+
/*dorisdump{"ts":"2024-08-06 23:44:12.047","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"18799575029447f9-a6a3fc65c8eda3f1"}*/ SHOW VARIABLES LIKE
77
'%time_zone%';
8-
/*dorisdump{"ts":"2024-08-06 23:44:13,048","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"18799575029447f9-a6a3fc65c8eda3f2"}*/ SHOW VARIABLES LIKE '%time_zone%';
8+
/*dorisdump{"ts":"2024-08-06 23:44:13.048","client":"192.168.48.118:51970","user":"root","db":"__internal_schema","queryId":"18799575029447f9-a6a3fc65c8eda3f2"}*/ SHOW VARIABLES LIKE '%time_zone%';

src/auditlog.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,9 @@ func (s *SimpleAuditLogScanner) validateSQL(queryId, stmt string) error {
258258

259259
func (s *SimpleAuditLogScanner) onMatch(caps []string, skipOptsFilter bool) {
260260
time, client, user, db, durationMs, queryId, stmt := caps[0], caps[1], caps[2], caps[3], caps[4], caps[5], caps[6]
261-
261+
time = strings.Replace(time, ",", ".", 1) // 2006-01-02 15:04:05,000 -> 2006-01-02 15:04:05.000
262262
stmt = strings.TrimSpace(stmt)
263+
263264
ok := s.filterStmtFromMatch(time, durationMs, queryId, stmt, skipOptsFilter)
264265
if !ok {
265266
return
@@ -308,10 +309,10 @@ func (s *SimpleAuditLogScanner) filterStmtFromMatch(
308309

309310
// filter by opts below
310311

311-
if s.From != "" && strings.SplitN(time, ",", 2)[0] < s.From {
312+
if s.From != "" && strings.SplitN(time, ".", 2)[0] < s.From {
312313
return false
313314
}
314-
if s.To != "" && strings.SplitN(time, ",", 2)[0] > s.To {
315+
if s.To != "" && strings.SplitN(time, ".", 2)[0] > s.To {
315316
return false
316317
}
317318

src/db.go

+46-40
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,8 @@ func ShowFronendsDisksDir(ctx context.Context, conn *sqlx.DB, diskType string) (
246246
break
247247
}
248248
}
249-
if err := r.Err(); err != nil {
250-
return dir, err
251-
}
252249

253-
return
250+
return dir, r.Err()
254251
}
255252

256253
func GetTablesStats(ctx context.Context, conn *sqlx.DB, dbname string, tables ...string) ([]*TableStats, error) {
@@ -444,51 +441,60 @@ func getDBAuditLogs(
444441
dbname, table string,
445442
conditions string,
446443
limit, offset int,
447-
) (string, string, error) {
448-
stmt := fmt.Sprintf("SELECT time, client_ip, user, db, query_time, query_id, stmt FROM `%s`.`%s` WHERE %s LIMIT %d OFFSET %d ORDER BY time asc, query_id asc",
449-
dbname,
450-
table,
451-
conditions,
452-
limit,
453-
offset,
454-
)
455-
logrus.Traceln("query audit log:", stmt)
456-
457-
var (
458-
r *sqlx.Rows
459-
err error
460-
retry int
461-
)
462-
const MaxRetry = 3
463-
for ; retry < MaxRetry; retry++ {
444+
) (lastTime string, lastQueryId string, err error) {
445+
const MaxRetry = 5
446+
for retry := 0; retry < MaxRetry; retry++ {
447+
stmt := fmt.Sprintf("SELECT time, client_ip, user, db, query_time, query_id, stmt FROM `%s`.`%s` WHERE %s ORDER BY time asc, query_id asc LIMIT %d OFFSET %d",
448+
dbname,
449+
table,
450+
conditions,
451+
limit,
452+
offset,
453+
)
454+
logrus.Traceln("query audit log:", stmt)
455+
456+
var r *sqlx.Rows
464457
r, err = db.QueryxContext(ctx, InternalSqlComment+stmt)
465-
if err == nil {
466-
break
458+
if err != nil {
459+
logrus.Errorf("query audit log table failed: retry: %d, db: %s, table: %s, err: %v\n", retry, dbname, table, err)
460+
continue
467461
}
468-
}
469-
if err != nil {
470-
logrus.Errorf("query audit log table failed: retry: %d, db: %s, table: %s, err: %v\n", retry, dbname, table, err)
471-
return "", "", err
472-
}
473-
defer r.Close()
462+
defer r.Close()
463+
464+
var i int
465+
for ; r.Next(); i++ {
466+
var (
467+
vals_ []any
468+
vals []string
469+
)
470+
471+
vals_, err = r.SliceScan()
472+
if err != nil {
473+
break
474+
}
474475

475-
var lastTime, lastQueryId string
476-
for i := 0; r.Next(); i++ {
477-
vals_, err := r.SliceScan()
478-
if err != nil {
479-
return "", "", err
476+
vals, err = cast.ToStringSliceE(vals_)
477+
if err != nil {
478+
logrus.Errorf("read audit log table failed: db: %s, table: %s, err: %v\n", dbname, table, err)
479+
break
480+
}
481+
lastTime, lastQueryId = vals[0], vals[5]
482+
logScan.onMatch(vals, true)
480483
}
481484

482-
vals, err := cast.ToStringSliceE(vals_)
485+
// prepare limit/offset for next retry
486+
limit -= i
487+
offset += i
488+
489+
_ = r.Close()
483490
if err != nil {
484-
logrus.Errorf("read audit log table failed: db: %s, table: %s, err: %v\n", dbname, table, err)
485-
return "", "", err
491+
continue
492+
} else if err = r.Err(); err == nil {
493+
break
486494
}
487-
lastTime, lastQueryId = vals[0], vals[5]
488-
logScan.onMatch(vals, true)
489495
}
490496

491-
return lastTime, lastQueryId, r.Err()
497+
return
492498
}
493499

494500
func SanitizeLike(s string) string {

src/replay.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
const (
2626
replaySqlPrefix = `/*dorisdump{`
2727
replaySqlSuffix = `*/`
28-
replayTsFormat = "2006-01-02 15:04:05,000"
28+
replayTsFormat = "2006-01-02 15:04:05.000"
2929
ReplayResultFileExt = ".result"
3030
)
3131

src/replay_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestDecodeReplaySqls(t *testing.T) {
2020
assert.NoError(t, err)
2121
defer replayFile.Close()
2222

23-
minTs, err := time.Parse("2006-01-02 15:04:05,000", "2024-08-06 23:44:11,041")
23+
minTs, err := time.Parse("2006-01-02 15:04:05.000", "2024-08-06 23:44:11.041")
2424
assert.NoError(t, err)
2525

2626
type args struct {

0 commit comments

Comments
 (0)