Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: add memory tracker for InsertExec and ReplaceExec #14179

Merged
merged 28 commits into from Dec 30, 2019

Conversation

XuHuaiyu
Copy link
Contributor

@XuHuaiyu XuHuaiyu commented Dec 23, 2019

What problem does this PR solve?

Before this commit, the memory usage of InsertExec and ReplaceExec is not traced.
For example,
we set the MemQuotaQuery in config.go to 32bytes.

We run the following SQLs, and check the tidb.log

tidb> show create table t;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                               |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t     | CREATE TABLE `t` (
  `a` bigint(20) DEFAULT NULL,
  `b` bigint(20) DEFAULT NULL,
  `c` bigint(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

tidb> insert into t values(1,1,1);
Query OK, 1 row affected (0.00 sec)

tidb> insert into t select * from t;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

From the tidb.log, we can ONLY got the out of memory message of the second sql, because that the second sql will read data from a TableReader, and the memory usage of the TableReader is already traced

[2019/12/23 17:09:57.907 +08:00] [WARN] [expensivequery.go:167] [expensive_query] [cost_time=0.000231972s] [stats=t:pseudo] [conn_id=1] [user=root] [database=test] [table_ids="[50]"] [txn_start_ts=413425257128132608] [mem_max="163 Bytes (163 Bytes)"] [sql="insert into t select * from t"]

After this commit, we can get the out-of-memory message of the 2 SQLs:

[2019/12/23 17:18:39.380 +08:00] [WARN] [expensivequery.go:167] [expensive_query] [cost_time=0.000015217s] [conn_id=1] [user=root] [database=test] [txn_start_ts=0] [mem_max="168 Bytes (168 Bytes)"] [sql="insert into t values(1,1,1)"]
[2019/12/23 17:18:45.029 +08:00] [WARN] [expensivequery.go:167] [expensive_query] [cost_time=0.000194098s] [stats=t:pseudo] [conn_id=1] [user=root] [database=test] [table_ids="[52]"] [txn_start_ts=413425395310002176] [mem_max="163 Bytes (163 Bytes)"] [sql="insert into t select * from t"]

What is changed and how it works?

Check List

Tests

  • Integration test

Code changes

  • Has exported function/method change
  • Has exported variable/fields change
  • Has interface methods change

Side effects

N/A

Related changes

N/A

Release note

N/A

@XuHuaiyu
Copy link
Contributor Author

/run-unit-test

@lysu lysu self-requested a review December 24, 2019 08:24
@XuHuaiyu XuHuaiyu marked this pull request as ready for review December 24, 2019 09:02
@XuHuaiyu XuHuaiyu requested a review from a team as a code owner December 24, 2019 09:02
@ghost ghost requested review from francis0407 and alivxxx and removed request for a team December 24, 2019 09:02
@XuHuaiyu
Copy link
Contributor Author

/re-run

executor/insert_common.go Outdated Show resolved Hide resolved
executor/insert_common.go Outdated Show resolved Hide resolved
session/txn.go Outdated
@@ -455,6 +461,9 @@ func (s *session) StmtCommit() error {
st.doNotCommit = err
return err
}
if memTracker != nil {
memTracker.Consume(int64(st.Transaction.Size()))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for situation like:

begin;
insert1
insert2
commit;

insert1 will add 1k to transaction buffer, insert2 will add 1k to transaction buffer.

so when insert2 step in here will +3k at here..

it's hard to track transaction memory in stmt level if one transaction have multiple statements. - -

@@ -431,7 +437,7 @@ func (s *session) getTxnFuture(ctx context.Context) *txnFuture {
}

// StmtCommit implements the sessionctx.Context interface.
func (s *session) StmtCommit() error {
func (s *session) StmtCommit(memTracker *memory.Tracker) error {
defer s.txn.cleanup()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we follow code logic, this defer maybe need memTracker.Consume(-int64(txn.Size())), before this line we have put all data from stmt buffer into transaction buffer, and this line will cleanup stmt buffer

@@ -202,6 +207,7 @@ func (e *ReplaceExec) exec(ctx context.Context, newRows [][]types.Datum) error {
return err
}
}
memTracker.Consume(int64(txn.Size()))
Copy link
Collaborator

@lysu lysu Dec 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also have potential be duplicate add consume amount if user use batch insert(although we are not recommend use batch insert)

exec be executed for each batch, so second batch will see first batch's memory still in stmt buffer

@XuHuaiyu
Copy link
Contributor Author

/run-all-tests

@XuHuaiyu
Copy link
Contributor Author

/run-all-tests

@@ -431,9 +437,13 @@ func (s *session) getTxnFuture(ctx context.Context) *txnFuture {
}

// StmtCommit implements the sessionctx.Context interface.
func (s *session) StmtCommit() error {
defer s.txn.cleanup()
func (s *session) StmtCommit(memTracker *memory.Tracker) error {
Copy link
Member

@jackysp jackysp Dec 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statement is finished and the memory is allocated when StmtCommit, I think it is meanless. Consume it at

return st.buf.Set(k, v)
.

Copy link
Contributor Author

@XuHuaiyu XuHuaiyu Dec 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But stmtBuffer can be GCed after be written to txnBuffer?

@XuHuaiyu
Copy link
Contributor Author

/run-unit-test

@XuHuaiyu
Copy link
Contributor Author

/run-unit-test

executor/insert.go Outdated Show resolved Hide resolved
@XuHuaiyu
Copy link
Contributor Author

/run-unit-test

executor/insert_common.go Outdated Show resolved Hide resolved
@@ -220,6 +232,8 @@ func insertRows(ctx context.Context, base insertCommon) (err error) {
}
rows = append(rows, row)
if batchInsert && e.rowCount%uint64(batchSize) == 0 {
memUsageOfRows = types.EstimatedMemUsage(rows[0], len(rows))
memTracker.Consume(memUsageOfRows)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For LoadDataExec, here is nil pointer??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoadDataExec will not touch here.

@XuHuaiyu
Copy link
Contributor Author

/run-all-tests

@tiancaiamao
Copy link
Contributor

LGTM

@tiancaiamao tiancaiamao added the status/LGT1 Indicates that a PR has LGTM 1. label Dec 30, 2019
Copy link
Collaborator

@lysu lysu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lysu lysu added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Dec 30, 2019
@XuHuaiyu XuHuaiyu merged commit c1bc9ff into pingcap:master Dec 30, 2019
@XuHuaiyu XuHuaiyu deleted the trace-write-memory branch December 30, 2019 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sig/execution SIG execution status/LGT2 Indicates that a PR has LGTM 2. type/enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants