1. 04 Jun, 2020 1 commit
    • Varun Gupta's avatar
      MDEV-22715: SIGSEGV in radixsort_for_str_ptr and in native_compare/my_qsort2 (optimized builds) · f30ff10c
      Varun Gupta authored
      For DECIMAL[(M[,D])] datatype max_sort_length was not being honoured which was leading to buffer
      overflow while making the sort key. The fix to this problem would be to create sort keys for decimals
      with atmost max_sort_key bytes
      
      Important:
      The minimum value of max_sort_length has been raised to 8 (previously was 4),
      so fixed size datatypes like DOUBLE and BIGINIT are not truncated for
      lower values of max_sort_length.
      f30ff10c
  2. 03 Jun, 2020 2 commits
  3. 02 Jun, 2020 1 commit
  4. 29 May, 2020 5 commits
    • Sergey Vojtovich's avatar
      Attempt fixing mroonga gcc 8 build failure · 49854811
      Sergey Vojtovich authored
      Part of MDEV-19061 - table_share used for reading statistical tables is
                           not protected
      49854811
    • Sergey Vojtovich's avatar
      Thread safe histograms loading · c2798784
      Sergey Vojtovich authored
      Previously multiple threads were allowed to load histograms concurrently.
      There were no known problems caused by this. But given amount of data
      races in this code, it'd happen sooner or later.
      
      To avoid scalability bottleneck, histograms loading is protected by
      per-TABLE_SHARE atomic variable.
      
      Whenever histograms were loaded by preceding statement (hot-path), a
      scalable load-acquire check is performed.
      
      Whenever histograms have to be loaded anew, mutual exclusion for loaders
      is established by atomic variable. If histograms are being loaded
      concurrently, statement waits until load is completed.
      
      - Table_statistics::total_hist_size moved to TABLE_STATISTICS_CB: only
        meaningful within TABLE_SHARE (not used for collected stats).
      - TABLE_STATISTICS_CB::histograms_can_be_read and
        TABLE_STATISTICS_CB::histograms_are_read are replaced with a tri state
        atomic variable.
      - Simplified away alloc_histograms_for_table_share().
      
      Note: there's still likely a data race if a thread attempts accessing
      histograms data after it failed to load it (because of concurrent load).
      It was there previously and goes out of the scope of this effort. One way
      of fixing it could be reviving TABLE::histograms_are_read and adding
      appropriate checks whenever it is needed.
      
      Part of MDEV-19061 - table_share used for reading statistical tables is
                           not protected
      c2798784
    • Sergey Vojtovich's avatar
      Thread safe statistics loading · 609a0d3d
      Sergey Vojtovich authored
      Previously multiple threads were allowed to load statistics concurrently.
      There were no known problems caused by this. But given amount of data
      races in this code, it'd happen sooner or later.
      
      To avoid scalability bottleneck, statistics loading is protected by
      per-TABLE_SHARE atomic variable.
      
      Whenever statistics were loaded by preceding statement (hot-path), a
      scalable load-acquire check is performed.
      
      Whenever statistics have to be loaded anew, mutual exclusion for loaders
      is established by atomic variable. If statistics are being loaded
      concurrently, statement waits until load is completed.
      
      TABLE_STATISTICS_CB::stats_can_be_read and
      TABLE_STATISTICS_CB::stats_is_read are replaced with a tri state atomic
      variable.
      
      Part of MDEV-19061 - table_share used for reading statistical tables is
                           not protected
      609a0d3d
    • Sergey Vojtovich's avatar
      Simplified away statistics_for_tables_is_needed() · 1055a7f4
      Sergey Vojtovich authored
      Removed redundant loops, integrated logics into the caller instead.
      Unified condition in read_statistics_for_tables(), less
      "table_share != NULL" checks, no more potential "table_share == NULL"
      dereferencing.
      
      Part of MDEV-19061 - table_share used for reading statistical tables is
                           not protected
      1055a7f4
    • Alexander Barkov's avatar
      MDEV-22744 *SAN: sql/item_xmlfunc.cc:791:43: runtime error: downcast of... · a2932e86
      Alexander Barkov authored
      MDEV-22744 *SAN: sql/item_xmlfunc.cc:791:43: runtime error: downcast of address ... which does not point to an object of type 'Item_func' note: object is of type 'Item_bool' (on optimized builds)
      
      In Item_nodeset_func_predicate::val_nodeset, args[1] is not necessarily
      an Item_func descendant. It can be Item_bool.
      
      Removing a wrong cast. It was not really needed anyway.
      a2932e86
  5. 28 May, 2020 2 commits
    • Anel Husakovic's avatar
      fix pre-definition for embedded server for find_user_or_anon() · a1b3bebe
      Anel Husakovic authored
      Pre-definitions are allowed for non-embedded.
      Failur catched with:
      ```
      cmake ../../10.1 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-9
      -DCMAKE_C_COMPILER=gcc-9 -DWITH_EMBEDDED_SERVER=ON -DCMAKE_BUILD_TYPE=Debug
      -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,PERFSCHEMA,SPIDER,SPHINX}=N
      -DMYSQL_MAINTAINER_MODE=ON -DNOT_FOR_DISTRIBUTION=ON
      ```
      Alternative fix would be
      ```
      --- a/sql/sql_acl.cc
      +++ b/sql/sql_acl.cc
      @@ -201,8 +201,10 @@ LEX_STRING current_user= { C_STRING_WITH_LEN("*current_user") };
       LEX_STRING current_role= { C_STRING_WITH_LEN("*current_role") };
       LEX_STRING current_user_and_current_role= { C_STRING_WITH_LEN("*current_user_and_current_role") };
      
      +#ifndef EMBEDDED_LIBRARY
       class ACL_USER;
       static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip);
      +#endif
      ```
      a1b3bebe
    • Anel Husakovic's avatar
      MDEV-22312: Bad error message for SET DEFAULT ROLE when user account is not granted the role · 957cb7b7
      Anel Husakovic authored
      - `SET DEFAULT ROLE xxx [FOR yyy]` should say:
        "User yyy has not been granted a role xxx" if:
          - The current user (not the user `yyy` in the FOR clause) can see the
          role xxx. It can see the role if:
            * role exists in `mysql.roles_mappings` (traverse the graph),
            * If the current user has read access on `mysql.user` table - in
          that case, it can see all roles, granted or not.
          - Otherwise it should be "Invalid role specification".
      
      In other words, it should not be possible to use `SET DEFAULT ROLE` to discover whether a specific role exist or not.
      957cb7b7
  6. 26 May, 2020 3 commits
    • Andrei Elkin's avatar
      MDEV-15152 Optimistic parallel slave doesnt cope well with START SLAVE UNTIL · dbe447a7
      Andrei Elkin authored
      The immediate bug was caused by a failure to recognize a correct
      position to stop the slave applier run in optimistic parallel mode.
      There were the following set of issues that the analysis unveil.
      1 incorrect estimate for the event binlog position passed to
        is_until_satisfied
      2 wait for workers to complete by the driver thread did not account non-group events
        that could be left unprocessed and thus to mix up the last executed
        binlog group's file and position:
        the file remained old and the position related to the new rotated file
      3 incorrect 'slave reached file:pos' by the parallel slave report in the error log
      4 relay log UNTIL missed out the parallel slave branch in
        is_until_satisfied.
      
      The patch addresses all of them to simplify logics of log change
      notification in either the master and relay-log until case.
      P.1 is addressed with passing the event into is_until_satisfied()
      for proper analisis by the function.
      P.2 is fixed by changes in handle_queued_pos_update().
      P.4 required removing relay-log change notification by workers.
      Instead the driver thread updates the notion of the current relay-log
      fully itself with aid of introduced
      bool Relay_log_info::until_relay_log_names_defer.
      
      An extra print out of the requested until file:pos is arranged
      with --log-warning=3.
      dbe447a7
    • Marko Mäkelä's avatar
      Merge 5.5 into 10.1 · adbf85fc
      Marko Mäkelä authored
      adbf85fc
    • Marko Mäkelä's avatar
      MDEV-22513 main.processlist_notembedded Timeout in wait_until_count_sessions · 9bbd685e
      Marko Mäkelä authored
      Do not blindly disconnect the connection that is in WAIT_FOR
      because it could happen that neither the disconnect nor the
      SIGNAL would be processed before RESET would discard the signal.
      9bbd685e
  7. 25 May, 2020 1 commit
  8. 22 May, 2020 1 commit
    • Alexander Barkov's avatar
      MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets... · cb9c49a9
      Alexander Barkov authored
      MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
      
      The code incorrectly assumed in multiple places that TYPELIB
      values cannot have 0x00 bytes inside. In fact they can:
      
        CREATE TABLE t1 (a ENUM(0x61, 0x0062) CHARACTER SET BINARY);
      
      Note, the TYPELIB value encoding used in FRM is ambiguous about 0x00.
      
      So this fix is partial.
      
      It fixes 0x00 bytes in many (but not all) places:
      
      - In the middle or in the end of a value:
          CREATE TABLE t1 (a ENUM(0x6100) ...);
          CREATE TABLE t1 (a ENUM(0x610062) ...);
      
      - In the beginning of the first value:
          CREATE TABLE t1 (a ENUM(0x0061));
          CREATE TABLE t1 (a ENUM(0x0061), b ENUM('b'));
      
      - In the beginning of the second (and following) value of the *last* ENUM/SET
        in the table:
      
          CREATE TABLE t1 (a ENUM('a',0x0061));
          CREATE TABLE t1 (a ENUM('a'), b ENUM('b',0x0061));
      
      However, it does not fix 0x00 when:
      
      - 0x00 byte is in the beginning of a value of a non-last ENUM/SET
        causes an error:
      
         CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b'));
         ERROR 1033 (HY000): Incorrect information in file: './test/t1.frm'
      
        This is an ambuguous case and will be fixed separately.
        We need a new TYPELIB encoding to fix this.
      
      Details:
      
      - unireg.cc
      
        The function pack_header() incorrectly used strlen() to detect
        a TYPELIB value length. Adding a new function typelib_values_packed_length()
        which uses TYPELIB::type_lengths[n] to detect the n-th value length,
        and reusing the new function in pack_header() and packed_fields_length()
      
      - table.cc
        fix_type_pointers() assumed in multiple places that values cannot have
        0x00 inside and used strlen(TYPELIB::type_names[n]) to set
        the corresponding TYPELIB::type_lengths[n].
      
        Also, fix_type_pointers() did not check the encoded data for consistency.
      
        Rewriting fix_type_pointers() code to populate TYPELIB::type_names[n] and
        TYPELIB::type_lengths[n] at the same time, so no additional loop
        with strlen() is needed any more.
      
        Adding many data consistency tests.
      
        Fixing the main loop in fix_type_pointers() to use memchr() instead of
        strchr() to handle 0x00 properly.
      
        Fixing create_key_infos() to return the result in a LEX_STRING rather
        that in a char*.
      cb9c49a9
  9. 20 May, 2020 3 commits
    • Sujatha's avatar
      MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from _my_b_write on... · 836d7089
      Sujatha authored
      MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from _my_b_write on CREATE after RESET MASTER
      
      Analysis:
      ========
      RESET MASTER TO # command deletes all binary log files listed in the index
      file, resets the binary log index file to be empty, and creates a new binary
      log with number #. When the user provided binary log number is greater than
      the max allowed value '2147483647' server fails to generate a new binary log.
      The RESET MASTER statement marks the binlog closure status as
      'LOG_CLOSE_TO_BE_OPENED' and exits. Statements which follow RESET MASTER
      try to write to binary log they find the log_state != LOG_CLOSED and
      proceed to write to binary log cache and it results in crash.
      
      Fix:
      ===
      During MYSQL_BIN_LOG open, if generation of new binary log name fails then the
      "log_state" needs to be marked as "LOG_CLOSED". With this further statements
      will find binary log as closed and they will skip writing to the binary log.
      836d7089
    • Rasmus Johansson's avatar
      MDEV-22631 fix · a6b4d4be
      Rasmus Johansson authored
      a6b4d4be
    • Marko Mäkelä's avatar
      MDEV-22258 Limit innodb_encryption_threads to 255 · 6b2c8cac
      Marko Mäkelä authored
      For no good reason, innodb_encryption_threads was limited to
      4,294,967,295. Expectedly, the server would crash if such an
      insane value was specified. Let us limit the maximum to 255.
      
      The encryption threads are not doing much useful work.
      They are basically only dirtying pages by performing
      dummy writes via the redo log. The encryption key rotation
      or the in-place addition or removal of encryption
      will take place in the page cleaner.
      
      In a quick test on a 20-core CPU (40 threads in total),
      the sweet spot on an otherwise idle server seemed to be
      innodb_encryption_threads=16 for the test
      encryption.encrypt_and_grep. The new limit 255 should be
      more than enough for even bigger servers.
      6b2c8cac
  10. 19 May, 2020 3 commits
  11. 18 May, 2020 2 commits
  12. 15 May, 2020 1 commit
    • Alexander Barkov's avatar
      MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column · 3df29727
      Alexander Barkov authored
      The code erroneously allowed both:
      INSERT INTO t1 (vcol) VALUES (DEFAULT);
      INSERT INTO t1 (vcol) VALUES (DEFAULT(non_virtual_column));
      
      The former is OK, but the latter is not.
      Adding a new virtual method in Item:
      
      virtual bool vcol_assignment_allowed_value() const { return false; }
      
      Item_null, Item_param and Item_default_value override it.
      
      Item_default_value overrides it in the way to:
      - allow DEFAULT
      - disallow DEFAULT(col)
      3df29727
  13. 14 May, 2020 4 commits
  14. 11 May, 2020 3 commits
  15. 08 May, 2020 3 commits
  16. 07 May, 2020 1 commit
    • Marko Mäkelä's avatar
      MDEV-22497 [ERROR] InnoDB: Unable to purge a record · 26aab96e
      Marko Mäkelä authored
      The InnoDB insert buffer was upgraded in MySQL 5.5 into a change
      buffer that also covers delete-mark and delete (purge) operations.
      
      There is an important constraint for delete operations: a B-tree
      leaf page must not become empty unless the entire tree becomes empty,
      consisting of an empty root page. Because change buffer merges only
      occur on a single leaf page at a time, delete operations must not be
      buffered if it is possible that the last record of the page could be
      deleted. (In that case, we would refuse to use the change buffer, and
      if we really delete the last record, we would shrink the index tree.)
      
      The function ibuf_get_volume_buffered_hash() is part of our insurance
      that the page would not become empty. It is supposed to map each
      buffered INSERT or DELETE_MARK record payload into a hash value.
      We will only count each such record as a distinct key if there is no
      hash collision. DELETE operations will always decrement the predicted
      number fo records in the page.
      
      Due to a bug in the function, we would actually compute the hash value
      not only on the record payload, but also on some following bytes,
      in case the record contains NULL values. In MySQL Bug #61104, we had
      some examples of this dating back to 2012. But back then, we failed to
      reproduce the bug, and in commit d84c9557
      we simply demoted the hard assertion to a message printout and a debug
      assertion failure.
      
      ibuf_get_volume_buffered_hash(): Correctly compute the hash value
      of the payload bytes only. Note: we will consider
      ('foo','bar'),(NULL,'foobar'),('foob','ar') to be equal, but this
      is not a problem, because in case of a hash collision, we could
      also consider ('boo','far') to be equal, and underestimate the number
      of records in the page, leading to refusing to buffer a DELETE.
      26aab96e
  17. 06 May, 2020 4 commits