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

MDEV-14821 Assertion !is_set() || (m_status == DA_OK_BULK && is_bulk_op()) failed in Diagnostics_area::set_ok_status #442

Merged
merged 8 commits into from
Jan 8, 2018

Conversation

kevgs
Copy link

@kevgs kevgs commented Jan 2, 2018

No description provided.

@kevgs kevgs added the bug label Jan 2, 2018
@kevgs kevgs self-assigned this Jan 2, 2018
@kevgs kevgs requested a review from midenok January 2, 2018 20:27
Copy link

@midenok midenok left a comment

Choose a reason for hiding this comment

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

Pruning is based on range constants. vers_update_range_constants() is required for correct pruning after stat changes.

@kevgs kevgs force-pushed the kevgs/mdev-14821/part_assert branch from 7057450 to c09be7c Compare January 3, 2018 21:39
@kevgs
Copy link
Author

kevgs commented Jan 3, 2018

Force fix part_column_list_val always (after each UPDATE, DELETE) to not read a freed memory from previous queries. Updated.

}
col_val->fixed= 0;
Copy link

Choose a reason for hiding this comment

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

Can you describe what exactly this fixes? Why you decided to refix col_val when it was not updated? Looks like ad hoc solution. Where Field_timestampf was constructed, where it was destroyed? I don't see such info in analysis.

Copy link
Author

Choose a reason for hiding this comment

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

Here is some info. Hope it's suitable to get the picture.

Why you decided to refix col_val when it was not updated? Looks like ad hoc solution.

Yes, you're right. It just fixes one of several observed errors: reading freed memory.

Where Field_timestampf was constructed, where it was destroyed?

We don't care because we don't touch it's memory. We touch a memory which this instance points to: TABLE::record[0]

Btw, 3 kinds of timestamp comparison problems happens also in partition.test. But tests pass :(

Do you have some thoughts on how to do a proper fix?

Copy link
Author

Choose a reason for hiding this comment

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

Btw, 3 kinds of timestamp comparison problems happens also in partition.test. But tests pass :(

That's partially incorrect: no freed memory read in partition.test.

Copy link

@midenok midenok Jan 4, 2018

Choose a reason for hiding this comment

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

This is not TABLE::record[0]: Field_timestampf::ptr can point to any arbitrary buffer. This is general scheme to fix premature destruction:

  1. Find where the buffer was allocated;
  2. Find where the buffer was freed;
  3. Find where the buffer was accessed;
  4. Fix allocation: use longer living pool which covers 1 and 3.

By word where I always mean stack traces.

Copy link
Author

Choose a reason for hiding this comment

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

#441 (comment)

thd->mem_root is ok for column_value of other types of partitioning but not enough for versioning partition.

Here is patch with another mem_root which is in use in partition_info.cc. Assertion failure disappears. What do you think about it?

diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index e1e83db7b31..d102d5bf379 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -2972,7 +2972,8 @@ bool partition_info::fix_column_value_functions(THD *thd,
         }
         thd->got_warning= save_got_warning;
         thd->variables.sql_mode= save_sql_mode;
-        if (!(val_ptr= (uchar*) thd->memdup(field->ptr, len)))
+        if (!(val_ptr= (uchar *)(vers_info ? memdup_root(&table->s->mem_root, field->ptr, len)
+                                           : thd->memdup(field->ptr, len))))
         {
           mem_alloc_error(len);
           result= TRUE;

Copy link

Choose a reason for hiding this comment

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

This certainly should not be TABLE_SHARE::mem_root as it is inter-thread.
Try this:

--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -562,7 +562,10 @@ class partition_info : public Sql_alloc
       Field *f= part_field_array[i];
       bitmap_set_bit(f->table->write_set, f->field_index);
     }
+    MEM_ROOT *old_root= thd->mem_root;
+    thd->mem_root= &table->mem_root;
     result= check_range_constants(thd, false);
+    thd->mem_root= old_root;
     vers_info->stat_serial= table->s->stat_serial;
     mysql_rwlock_unlock(&table->s->LOCK_stat_serial);
     return result;

or find connection-wide mem_root.

Copy link
Author

Choose a reason for hiding this comment

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

That worked. PR updated.

insert into t1 values (1,10),(2,20),(3,30);
update t1 set b = 0;
alter table t1 partition by system_time interval 1 second ( partition p1 history, partition p2 history, partition pn current );
--sleep 2
Copy link

Choose a reason for hiding this comment

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

Is it reproducible via LIMIT? I don't like 2 seconds delay in test.

Copy link
Author

Choose a reason for hiding this comment

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

I failed to reproduce it with limit.

Copy link

Choose a reason for hiding this comment

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

Rebase on trunk and use this case:

create or replace table t1 (x int) with system versioning;
insert into t1 values (0), (1);
update t1 set x= x + 1;
alter table t1 partition by system_time limit 1 (
    partition p1 history,
    partition p2 history,
    partition pn current);
delete from t1 where x = 1;
delete from t1 where x = 2;

Merge when done.

@kevgs kevgs force-pushed the kevgs/mdev-14821/part_assert branch 2 times, most recently from e593c83 to 2dfbbcc Compare January 4, 2018 21:45
@kevgs kevgs force-pushed the kevgs/mdev-14821/part_assert branch from 2dfbbcc to ad101dc Compare January 8, 2018 10:26
@kevgs kevgs merged commit 5dddbaf into trunk Jan 8, 2018
@kevgs kevgs deleted the kevgs/mdev-14821/part_assert branch September 28, 2018 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants