~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/srv/srv0srv.cc

mergeĀ lp:~hingo/drizzle/drizzle-auth_ldap-fix-and-docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, 2009 Google Inc.
5
 
Copyright (c) 2009, Percona Inc.
 
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
 
4
Copyright (C) 2008, 2009 Google Inc.
 
5
Copyright (C) 2009, Percona Inc.
6
6
 
7
7
Portions of this file contain modifications contributed and copyrighted by
8
8
Google, Inc. Those modifications are gratefully acknowledged and are described
60
60
/* Dummy comment */
61
61
#include "srv0srv.h"
62
62
 
 
63
#include <drizzled/error.h>
 
64
#include <drizzled/errmsg_print.h>
 
65
 
63
66
#include "ut0mem.h"
64
67
#include "ut0ut.h"
65
68
#include "os0proc.h"
106
109
 
107
110
UNIV_INTERN const char* srv_main_thread_op_info = "";
108
111
 
109
 
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
110
 
UNIV_INTERN const char  srv_mysql50_table_name_prefix[9] = "#mysql50#";
111
 
 
112
112
/* Server parameters which are read from the initfile */
113
113
 
114
114
/* The following three are dir paths which are catenated before file
204
204
/** The sort order table of the MySQL latin1_swedish_ci character set
205
205
collation */
206
206
#if defined(BUILD_DRIZZLE)
207
 
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
 
207
const byte      srv_latin1_ordering[256]        /* The sort order table of the latin1
208
208
                                        character set. The following table is
209
209
                                        the MySQL order as of Feb 10th, 2002 */
210
210
= {
266
266
UNIV_INTERN ulint       srv_n_read_io_threads   = ULINT_MAX;
267
267
UNIV_INTERN ulint       srv_n_write_io_threads  = ULINT_MAX;
268
268
 
 
269
/* The universal page size of the database */
 
270
UNIV_INTERN ulint       srv_page_size_shift     = 0;
 
271
UNIV_INTERN ulint       srv_page_size           = 0;
 
272
 
 
273
/* The log block size */
 
274
UNIV_INTERN uint32_t    srv_log_block_size      = 0;
 
275
 
269
276
/* User settable value of the number of pages that must be present
270
277
in the buffer cache and accessed sequentially for InnoDB to trigger a
271
278
readahead request. */
355
362
reading of a disk page */
356
363
UNIV_INTERN ulint srv_buf_pool_reads = 0;
357
364
 
 
365
/** Time in seconds between automatic buffer pool dumps */
 
366
UNIV_INTERN uint srv_auto_lru_dump = 0;
 
367
 
358
368
/* structure to pass status variables to MySQL */
359
369
UNIV_INTERN export_struc export_vars;
360
370
 
433
443
 
434
444
UNIV_INTERN ulong       srv_replication_delay           = 0;
435
445
 
 
446
UNIV_INTERN uint64_t    srv_ibuf_max_size = 0;
 
447
UNIV_INTERN uint32_t    srv_ibuf_active_contract = 0;
 
448
UNIV_INTERN uint32_t    srv_ibuf_accel_rate = 100;
 
449
 
 
450
#define PCT_IBUF_IO(pct) (srv_io_capacity * srv_ibuf_accel_rate \
 
451
                          * (pct / 10000.0))
 
452
 
 
453
UNIV_INTERN uint32_t    srv_checkpoint_age_target = 0;
 
454
UNIV_INTERN uint32_t    srv_flush_neighbor_pages = 1;
 
455
 
 
456
UNIV_INTERN uint32_t    srv_read_ahead = 3; /* 1: random, 2: linear, 3: both */
 
457
UNIV_INTERN uint32_t    srv_adaptive_flushing_method = 0; /* 0: native,
 
458
                                                             1: estimate,
 
459
                                                             2: keep_average */
 
460
 
 
461
UNIV_INTERN ibool srv_read_only = FALSE;
 
462
UNIV_INTERN ibool srv_fake_write = FALSE;
 
463
UNIV_INTERN ibool srv_apply_log_only = FALSE;
 
464
 
436
465
/*-------------------------------------------*/
437
466
UNIV_INTERN ulong       srv_n_spin_wait_rounds  = 30;
438
467
UNIV_INTERN ulong       srv_n_free_tickets_to_enter = 500;
491
520
#ifdef UNIV_PFS_MUTEX
492
521
/* Key to register kernel_mutex with performance schema */
493
522
UNIV_INTERN mysql_pfs_key_t     kernel_mutex_key;
 
523
/* Key to protect writing the commit_id to the sys header */
 
524
UNIV_INTERN mysql_pfs_key_t     commit_id_mutex_key;
494
525
/* Key to register srv_innodb_monitor_mutex with performance schema */
495
526
UNIV_INTERN mysql_pfs_key_t     srv_innodb_monitor_mutex_key;
496
527
/* Key to register srv_monitor_file_mutex with performance schema */
734
765
/* Table for MySQL threads where they will be suspended to wait for locks */
735
766
UNIV_INTERN srv_slot_t* srv_mysql_table = NULL;
736
767
 
 
768
UNIV_INTERN os_event_t  srv_timeout_event;
 
769
 
 
770
UNIV_INTERN os_event_t  srv_monitor_event;
 
771
 
 
772
UNIV_INTERN os_event_t  srv_error_event;
 
773
 
737
774
UNIV_INTERN os_event_t  srv_lock_timeout_thread_event;
738
775
 
739
776
UNIV_INTERN srv_sys_t*  srv_sys = NULL;
743
780
UNIV_INTERN byte        srv_pad1[64];
744
781
/* mutex protecting the server, trx structs, query threads, and lock table */
745
782
UNIV_INTERN mutex_t*    kernel_mutex_temp;
 
783
/* mutex protecting the sys header for writing the commit id */
 
784
UNIV_INTERN mutex_t*    commit_id_mutex_temp;
 
785
 
746
786
/* padding to prevent other memory update hotspots from residing on
747
787
the same memory cache line */
748
788
UNIV_INTERN byte        srv_pad2[64];
904
944
 
905
945
        slot = srv_table_get_nth_slot(slot_no);
906
946
 
907
 
        type = slot->type;
 
947
        type = static_cast<srv_thread_type>(slot->type);
908
948
 
909
949
        ut_ad(type >= SRV_WORKER);
910
950
        ut_ad(type <= SRV_MASTER);
947
987
 
948
988
                slot = srv_table_get_nth_slot(i);
949
989
 
950
 
                if (slot->in_use && slot->type == type && slot->suspended) {
 
990
                if (slot->in_use &&
 
991
                    (static_cast<srv_thread_type>(slot->type) == type) &&
 
992
                    slot->suspended) {
951
993
 
952
994
                        slot->suspended = FALSE;
953
995
 
992
1034
 
993
1035
        slot = srv_table_get_nth_slot(slot_no);
994
1036
 
995
 
        type = slot->type;
 
1037
        type = static_cast<srv_thread_type>(slot->type);
996
1038
 
997
1039
        ut_ad(type >= SRV_WORKER);
998
1040
        ut_ad(type <= SRV_MASTER);
1013
1055
        srv_slot_t*             slot;
1014
1056
        ulint                   i;
1015
1057
 
1016
 
        srv_sys = mem_alloc(sizeof(srv_sys_t));
 
1058
        srv_sys = static_cast<srv_sys_t *>(mem_alloc(sizeof(srv_sys_t)));
1017
1059
 
1018
 
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
 
1060
        kernel_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
1019
1061
        mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
1020
1062
 
 
1063
        commit_id_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
 
1064
        mutex_create(commit_id_mutex_key, &commit_id_mutex, SYNC_COMMIT_ID_LOCK);
 
1065
 
1021
1066
        mutex_create(srv_innodb_monitor_mutex_key,
1022
1067
                     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
1023
1068
 
1024
 
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
1069
        srv_sys->threads = static_cast<srv_table_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
1025
1070
 
1026
1071
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1027
1072
                slot = srv_table_get_nth_slot(i);
1031
1076
                ut_a(slot->event);
1032
1077
        }
1033
1078
 
1034
 
        srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
1079
        srv_mysql_table = static_cast<srv_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
1035
1080
 
1036
1081
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1037
1082
                slot = srv_mysql_table + i;
1041
1086
                ut_a(slot->event);
1042
1087
        }
1043
1088
 
 
1089
        srv_error_event = os_event_create(NULL);
 
1090
 
 
1091
        srv_timeout_event = os_event_create(NULL);
 
1092
 
 
1093
        srv_monitor_event = os_event_create(NULL);
 
1094
 
1044
1095
        srv_lock_timeout_thread_event = os_event_create(NULL);
1045
1096
 
1046
1097
        for (i = 0; i < SRV_MASTER + 1; i++) {
1067
1118
 
1068
1119
        UT_LIST_INIT(srv_conc_queue);
1069
1120
 
1070
 
        srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
 
1121
        srv_conc_slots = static_cast<srv_conc_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t)));
1071
1122
 
1072
1123
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1073
1124
                conc_slot = srv_conc_slots + i;
1100
1151
        mem_free(srv_mysql_table);
1101
1152
        srv_mysql_table = NULL;
1102
1153
 
 
1154
        mem_free(commit_id_mutex_temp);
 
1155
        commit_id_mutex_temp = NULL;
 
1156
 
1103
1157
        trx_i_s_cache_free(trx_i_s_cache);
1104
1158
}
1105
1159
 
1920
1974
                (ulong) srv_conc_n_waiting_threads);
1921
1975
 
1922
1976
        fprintf(file, "%lu read views open inside InnoDB\n",
1923
 
                UT_LIST_GET_LEN(trx_sys->view_list));
 
1977
                static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)));
1924
1978
 
1925
1979
        n_reserved = fil_space_get_n_reserved_extents(0);
1926
1980
        if (n_reserved > 0) {
2070
2124
os_thread_ret_t
2071
2125
srv_monitor_thread(
2072
2126
/*===============*/
2073
 
        void*   arg __attribute__((unused)))
 
2127
        void*   /*arg __attribute__((unused))*/)
2074
2128
                        /*!< in: a dummy parameter required by
2075
2129
                        os_thread_create */
2076
2130
{
 
2131
        ib_int64_t      sig_count;
2077
2132
        double          time_elapsed;
2078
2133
        time_t          current_time;
2079
2134
        time_t          last_table_monitor_time;
2091
2146
        pfs_register_thread(srv_monitor_thread_key);
2092
2147
#endif
2093
2148
 
2094
 
        UT_NOT_USED(arg);
2095
 
        srv_last_monitor_time = time(NULL);
2096
 
        last_table_monitor_time = time(NULL);
2097
 
        last_tablespace_monitor_time = time(NULL);
2098
 
        last_monitor_time = time(NULL);
 
2149
        srv_last_monitor_time = ut_time();
 
2150
        last_table_monitor_time = ut_time();
 
2151
        last_tablespace_monitor_time = ut_time();
 
2152
        last_monitor_time = ut_time();
2099
2153
        mutex_skipped = 0;
2100
2154
        last_srv_print_monitor = srv_print_innodb_monitor;
2101
2155
loop:
2102
2156
        srv_monitor_active = TRUE;
2103
2157
 
2104
2158
        /* Wake up every 5 seconds to see if we need to print
2105
 
        monitor information. */
2106
 
 
2107
 
        os_thread_sleep(5000000);
2108
 
 
2109
 
        current_time = time(NULL);
 
2159
        monitor information or if signalled at shutdown. */
 
2160
 
 
2161
        sig_count = os_event_reset(srv_monitor_event);
 
2162
 
 
2163
        os_event_wait_time_low(srv_monitor_event, 5000000, sig_count);
 
2164
 
 
2165
        current_time = ut_time();
2110
2166
 
2111
2167
        time_elapsed = difftime(current_time, last_monitor_time);
2112
2168
 
2113
2169
        if (time_elapsed > 15) {
2114
 
                last_monitor_time = time(NULL);
 
2170
                last_monitor_time = ut_time();
2115
2171
 
2116
2172
                if (srv_print_innodb_monitor) {
2117
2173
                        /* Reset mutex_skipped counter everytime
2155
2211
                if (srv_print_innodb_tablespace_monitor
2156
2212
                    && difftime(current_time,
2157
2213
                                last_tablespace_monitor_time) > 60) {
2158
 
                        last_tablespace_monitor_time = time(NULL);
 
2214
                        last_tablespace_monitor_time = ut_time();
2159
2215
 
2160
2216
                        fputs("========================"
2161
2217
                              "========================\n",
2181
2237
                if (srv_print_innodb_table_monitor
2182
2238
                    && difftime(current_time, last_table_monitor_time) > 60) {
2183
2239
 
2184
 
                        last_table_monitor_time = time(NULL);
 
2240
                        last_table_monitor_time = ut_time();
2185
2241
 
2186
2242
                        fputs("===========================================\n",
2187
2243
                              stderr);
2233
2289
os_thread_ret_t
2234
2290
srv_lock_timeout_thread(
2235
2291
/*====================*/
2236
 
        void*   arg __attribute__((unused)))
 
2292
        void*   /*arg __attribute__((unused))*/)
2237
2293
                        /* in: a dummy parameter required by
2238
2294
                        os_thread_create */
2239
2295
{
2241
2297
        ibool           some_waits;
2242
2298
        double          wait_time;
2243
2299
        ulint           i;
 
2300
        ib_int64_t      sig_count;
2244
2301
 
2245
2302
#ifdef UNIV_PFS_THREAD
2246
2303
        pfs_register_thread(srv_lock_timeout_thread_key);
2247
2304
#endif
2248
2305
 
2249
2306
loop:
 
2307
 
2250
2308
        /* When someone is waiting for a lock, we wake up every second
2251
2309
        and check if a timeout has passed for a lock wait */
2252
2310
 
2253
 
        os_thread_sleep(1000000);
 
2311
        sig_count = os_event_reset(srv_timeout_event);
 
2312
 
 
2313
        os_event_wait_time_low(srv_timeout_event, 1000000, sig_count);
2254
2314
 
2255
2315
        srv_lock_timeout_active = TRUE;
2256
2316
 
2337
2397
os_thread_ret_t
2338
2398
srv_error_monitor_thread(
2339
2399
/*=====================*/
2340
 
        void*   arg __attribute__((unused)))
 
2400
        void*   /*arg __attribute__((unused))*/)
2341
2401
                        /*!< in: a dummy parameter required by
2342
2402
                        os_thread_create */
2343
2403
{
2345
2405
        ulint           fatal_cnt       = 0;
2346
2406
        ib_uint64_t     old_lsn;
2347
2407
        ib_uint64_t     new_lsn;
 
2408
        ib_int64_t      sig_count;
2348
2409
 
2349
2410
        old_lsn = srv_start_lsn;
2350
2411
 
2366
2427
        new_lsn = log_get_lsn();
2367
2428
 
2368
2429
        if (new_lsn < old_lsn) {
2369
 
                ut_print_timestamp(stderr);
2370
 
                fprintf(stderr,
2371
 
                        "  InnoDB: Error: old log sequence number %"PRIu64""
2372
 
                        " was greater\n"
2373
 
                        "InnoDB: than the new log sequence number %"PRIu64"!\n"
2374
 
                        "InnoDB: Please submit a bug report"
2375
 
                        " to http://bugs.mysql.com\n",
2376
 
                        old_lsn, new_lsn);
 
2430
          drizzled::errmsg_printf(drizzled::error::INFO,
 
2431
                                  "InnoDB: Error: old log sequence number %"PRIu64" was greater than the new log sequence number %"PRIu64"!"
 
2432
                                  "InnoDB: Please submit a bug report to http://bugs.launchpad.net/drizzle",
 
2433
                                  old_lsn, new_lsn);
2377
2434
        }
2378
2435
 
2379
2436
        old_lsn = new_lsn;
2420
2477
 
2421
2478
        fflush(stderr);
2422
2479
 
2423
 
        os_thread_sleep(1000000);
 
2480
        sig_count = os_event_reset(srv_error_event);
 
2481
 
 
2482
        os_event_wait_time_low(srv_error_event, 1000000, sig_count);
2424
2483
 
2425
2484
        if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
2426
2485
 
2437
2496
        OS_THREAD_DUMMY_RETURN;
2438
2497
}
2439
2498
 
 
2499
/*********************************************************************//**
 
2500
A thread which restores the buffer pool from a dump file on startup and does
 
2501
periodic buffer pool dumps.
 
2502
@return a dummy parameter */
 
2503
UNIV_INTERN
 
2504
os_thread_ret_t
 
2505
srv_LRU_dump_restore_thread(
 
2506
/*====================*/
 
2507
        void*   /*arg __attribute__((unused))*/)
 
2508
/*!< in: a dummy parameter required by
 
2509
os_thread_create */
 
2510
{
 
2511
        uint    auto_lru_dump;
 
2512
        time_t  last_dump_time;
 
2513
        time_t  time_elapsed;
 
2514
 
 
2515
#ifdef UNIV_DEBUG_THREAD_CREATION
 
2516
        fprintf(stderr, "The LRU dump/restore thread has started, id %lu\n",
 
2517
                os_thread_pf(os_thread_get_curr_id()));
 
2518
#endif
 
2519
 
 
2520
        if (srv_auto_lru_dump)
 
2521
                buf_LRU_file_restore();
 
2522
 
 
2523
        last_dump_time = time(NULL);
 
2524
 
 
2525
loop:
 
2526
        os_thread_sleep(5000000);
 
2527
 
 
2528
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
 
2529
                goto exit_func;
 
2530
        }
 
2531
 
 
2532
        time_elapsed = time(NULL) - last_dump_time;
 
2533
        auto_lru_dump = srv_auto_lru_dump;
 
2534
        if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
 
2535
                last_dump_time = time(NULL);
 
2536
                buf_LRU_file_dump();
 
2537
        }
 
2538
 
 
2539
        goto loop;
 
2540
exit_func:
 
2541
        /* We count the number of threads in os_thread_exit(). A created
 
2542
        thread should always use that to exit and not use return() to exit. */
 
2543
 
 
2544
        os_thread_exit(NULL);
 
2545
 
 
2546
        OS_THREAD_DUMMY_RETURN;
 
2547
}
 
2548
 
2440
2549
/**********************************************************************//**
2441
2550
Check whether any background thread is active.
2442
2551
@return FALSE if all are are suspended or have exited. */
2599
2708
os_thread_ret_t
2600
2709
srv_master_thread(
2601
2710
/*==============*/
2602
 
        void*   arg __attribute__((unused)))
 
2711
        void*   /*arg __attribute__((unused))*/)
2603
2712
                        /*!< in: a dummy parameter required by
2604
2713
                        os_thread_create */
2605
2714
{
2609
2718
        ulint           n_pages_purged  = 0;
2610
2719
        ulint           n_bytes_merged;
2611
2720
        ulint           n_pages_flushed;
 
2721
        uint32_t        n_pages_flushed_prev = 0;
2612
2722
        ulint           n_bytes_archived;
2613
2723
        ulint           n_tables_to_drop;
2614
2724
        ulint           n_ios;
2616
2726
        ulint           n_ios_very_old;
2617
2727
        ulint           n_pend_ios;
2618
2728
        ulint           next_itr_time;
 
2729
        uint32_t        prev_adaptive_flushing_method = ULINT32_UNDEFINED;
 
2730
        uint32_t        inner_loop = 0;
 
2731
        bool            skip_sleep = false;
2619
2732
        ulint           i;
2620
2733
 
 
2734
        struct t_prev_flush_info_struct {
 
2735
            uint32_t    count;
 
2736
            uint32_t    space;
 
2737
            uint32_t    offset;
 
2738
            uint64_t    oldest_modification;
 
2739
        } prev_flush_info[MAX_BUFFER_POOLS];
 
2740
 
 
2741
        uint64_t        lsn_old;
 
2742
        uint64_t        oldest_lsn;
 
2743
 
2621
2744
#ifdef UNIV_DEBUG_THREAD_CREATION
2622
2745
        fprintf(stderr, "Master thread starts, id %lu\n",
2623
2746
                os_thread_pf(os_thread_get_curr_id()));
2638
2761
 
2639
2762
        mutex_exit(&kernel_mutex);
2640
2763
 
 
2764
        mutex_enter(&(log_sys->mutex));
 
2765
        lsn_old = log_sys->lsn;
 
2766
        mutex_exit(&(log_sys->mutex));
2641
2767
loop:
2642
2768
        /*****************************************************************/
2643
2769
        /* ---- When there is database activity by users, we cycle in this
2668
2794
        /* Sleep for 1 second on entrying the for loop below the first time. */
2669
2795
        next_itr_time = ut_time_ms() + 1000;
2670
2796
 
 
2797
        skip_sleep = false;
 
2798
 
2671
2799
        for (i = 0; i < 10; i++) {
2672
2800
                ulint   cur_time = ut_time_ms();
2673
2801
 
2674
 
                buf_get_total_stat(&buf_stat);
2675
 
 
2676
 
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2677
 
                        + buf_stat.n_pages_written;
2678
 
 
2679
 
                srv_main_thread_op_info = "sleeping";
2680
 
                srv_main_1_second_loops++;
2681
 
 
2682
 
                if (next_itr_time > cur_time) {
2683
 
 
2684
 
                        /* Get sleep interval in micro seconds. We use
2685
 
                        ut_min() to avoid long sleep in case of
2686
 
                        wrap around. */
2687
 
                        os_thread_sleep(ut_min(1000000,
2688
 
                                        (next_itr_time - cur_time)
2689
 
                                         * 1000));
2690
 
                        srv_main_sleeps++;
2691
 
                }
2692
 
 
2693
 
                /* Each iteration should happen at 1 second interval. */
2694
 
                next_itr_time = ut_time_ms() + 1000;
 
2802
                n_pages_flushed = 0;
2695
2803
 
2696
2804
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2697
2805
                can drop tables lazily after there no longer are SELECT
2708
2816
                        goto background_loop;
2709
2817
                }
2710
2818
 
 
2819
                buf_get_total_stat(&buf_stat);
 
2820
 
 
2821
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
 
2822
                        + buf_stat.n_pages_written;
 
2823
 
 
2824
                srv_main_thread_op_info = "sleeping";
 
2825
                srv_main_1_second_loops++;
 
2826
 
 
2827
                if (skip_sleep == false) {
 
2828
                    if (next_itr_time > cur_time
 
2829
                        && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
 
2830
 
 
2831
                        /* Get sleep interval in micro seconds. We use
 
2832
                           ut_min() to avoid long sleep in case of
 
2833
                           wrap around. */
 
2834
                        os_thread_sleep(ut_min(1000000,
 
2835
                                               (next_itr_time - cur_time)
 
2836
                                               * 1000));
 
2837
                        srv_main_sleeps++;
 
2838
 
 
2839
                        /*
 
2840
                          TODO: tracing code unported to Drizzle
 
2841
                          mutex_enter(&(log_sys->mutex));
 
2842
                          oldest_lsn = buf_pool_get_oldest_modification();
 
2843
                          ib_uint64_t   lsn = log_sys->lsn;
 
2844
                          mutex_exit(&(log_sys->mutex));
 
2845
 
 
2846
                          if(oldest_lsn)
 
2847
                              fprintf(stderr,
 
2848
                                      "InnoDB flush: age pct: %lu, lsn progress: %lu\n",
 
2849
                                      (lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
 
2850
                                      lsn - lsn_old);
 
2851
                        */
 
2852
 
 
2853
                    }
 
2854
 
 
2855
                    /* Each iteration should happen at 1 second interval. */
 
2856
                    next_itr_time = ut_time_ms() + 1000;
 
2857
                }
 
2858
 
 
2859
                skip_sleep = false;
 
2860
 
2711
2861
                /* Flush logs if needed */
2712
2862
                srv_sync_log_buffer_in_background();
2713
2863
 
2726
2876
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2727
2877
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
2728
2878
                        srv_main_thread_op_info = "doing insert buffer merge";
2729
 
                        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
 
2879
                        ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
2730
2880
 
2731
2881
                        /* Flush logs if needed */
2732
2882
                        srv_sync_log_buffer_in_background();
2743
2893
                        n_pages_flushed = buf_flush_list(
2744
2894
                                PCT_IO(100), IB_ULONGLONG_MAX);
2745
2895
 
2746
 
                } else if (srv_adaptive_flushing) {
 
2896
                        mutex_enter(&(log_sys->mutex));
 
2897
                        lsn_old = log_sys->lsn;
 
2898
                        mutex_exit(&(log_sys->mutex));
 
2899
                        prev_adaptive_flushing_method = ULINT32_UNDEFINED;
 
2900
                } else if (srv_adaptive_flushing
 
2901
                           && srv_adaptive_flushing_method == 0) {
2747
2902
 
2748
2903
                        /* Try to keep the rate of flushing of dirty
2749
2904
                        pages such that redo log generation does not
2759
2914
                                                n_flush,
2760
2915
                                                IB_ULONGLONG_MAX);
2761
2916
                        }
 
2917
 
 
2918
                        mutex_enter(&(log_sys->mutex));
 
2919
                        lsn_old = log_sys->lsn;
 
2920
                        mutex_exit(&(log_sys->mutex));
 
2921
                        prev_adaptive_flushing_method = ULINT32_UNDEFINED;
 
2922
                } else if (srv_adaptive_flushing
 
2923
                           && srv_adaptive_flushing_method == 1) {
 
2924
 
 
2925
                        /* Try to keep modified age not to exceed
 
2926
                           max_checkpoint_age * 7/8 line */
 
2927
 
 
2928
                        mutex_enter(&(log_sys->mutex));
 
2929
 
 
2930
                        oldest_lsn = buf_pool_get_oldest_modification();
 
2931
                        if (oldest_lsn == 0) {
 
2932
                                lsn_old = log_sys->lsn;
 
2933
                                mutex_exit(&(log_sys->mutex));
 
2934
 
 
2935
                        } else {
 
2936
                                if ((log_sys->lsn - oldest_lsn)
 
2937
                                    > (log_sys->max_checkpoint_age)
 
2938
                                    - ((log_sys->max_checkpoint_age) / 8)) {
 
2939
                                        /* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
 
2940
                                        /* We should not flush from here. */
 
2941
                                        lsn_old = log_sys->lsn;
 
2942
                                        mutex_exit(&(log_sys->mutex));
 
2943
                                } else if ((log_sys->lsn - oldest_lsn)
 
2944
                                           > (log_sys->max_checkpoint_age)/4) {
 
2945
 
 
2946
                                        /* defence line (max_checkpoint_age * 1/2) */
 
2947
                                        uint64_t        lsn = log_sys->lsn;
 
2948
 
 
2949
                                        uint64_t        level, bpl;
 
2950
                                        buf_page_t*     bpage;
 
2951
                                        ulint           j;
 
2952
 
 
2953
                                        mutex_exit(&(log_sys->mutex));
 
2954
 
 
2955
                                        bpl = 0;
 
2956
 
 
2957
                                        for (j = 0; j < srv_buf_pool_instances; j++) {
 
2958
                                                buf_pool_t*     buf_pool;
 
2959
                                                uint32_t        n_blocks = 0;
 
2960
 
 
2961
                                                buf_pool = buf_pool_from_array(j);
 
2962
 
 
2963
                                                /* The scanning flush_list is optimistic here */
 
2964
 
 
2965
                                                level = 0;
 
2966
                                                bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
 
2967
 
 
2968
                                                while (bpage != NULL) {
 
2969
                                                        uint64_t        oldest_modification = bpage->oldest_modification;
 
2970
                                                        if (oldest_modification != 0) {
 
2971
                                                                level += log_sys->max_checkpoint_age
 
2972
                                                                        - (lsn - oldest_modification);
 
2973
                                                        }
 
2974
                                                        bpage = UT_LIST_GET_NEXT(list, bpage);
 
2975
                                                        n_blocks++;
 
2976
                                                }
 
2977
 
 
2978
                                                if (level) {
 
2979
                                                        bpl += ((ib_uint64_t) n_blocks * n_blocks
 
2980
                                                                * (lsn - lsn_old)) / level;
 
2981
                                                }
 
2982
 
 
2983
                                        }
 
2984
 
 
2985
                                        if (!srv_use_doublewrite_buf) {
 
2986
                                                /* flush is faster than when doublewrite */
 
2987
                                                bpl = (bpl * 7) / 8;
 
2988
                                        }
 
2989
 
 
2990
                                        if (bpl) {
 
2991
retry_flush_batch:
 
2992
                                                n_pages_flushed = buf_flush_list(bpl,
 
2993
                                                                                 oldest_lsn + (lsn - lsn_old));
 
2994
                                                if (n_pages_flushed == ULINT32_UNDEFINED) {
 
2995
                                                        os_thread_sleep(5000);
 
2996
                                                        goto retry_flush_batch;
 
2997
                                                }
 
2998
                                        }
 
2999
 
 
3000
                                        lsn_old = lsn;
 
3001
                                        /*
 
3002
                                          TODO: tracing code unported to Drizzle
 
3003
                                          fprintf(stderr,
 
3004
                                                  "InnoDB flush: age pct: %lu, lsn progress: %lu, blocks to flush:%llu\n",
 
3005
                                                  (lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
 
3006
                                                  lsn - lsn_old, bpl);
 
3007
                                        */
 
3008
                                } else {
 
3009
                                        lsn_old = log_sys->lsn;
 
3010
                                        mutex_exit(&(log_sys->mutex));
 
3011
                                }
 
3012
                        }
 
3013
                        prev_adaptive_flushing_method = 1;
 
3014
                } else if (srv_adaptive_flushing && srv_adaptive_flushing_method == 2) {
 
3015
                        buf_pool_t*     buf_pool;
 
3016
                        buf_page_t*     bpage;
 
3017
                        uint64_t        lsn;
 
3018
                        ulint           j;
 
3019
 
 
3020
                        mutex_enter(&(log_sys->mutex));
 
3021
                        oldest_lsn = buf_pool_get_oldest_modification();
 
3022
                        lsn = log_sys->lsn;
 
3023
                        mutex_exit(&(log_sys->mutex));
 
3024
 
 
3025
                        /* upper loop/sec. (x10) */
 
3026
                        next_itr_time -= 900; /* 1000 - 900 == 100 */
 
3027
                        inner_loop++;
 
3028
                        if (inner_loop < 10) {
 
3029
                                i--;
 
3030
                        } else {
 
3031
                                inner_loop = 0;
 
3032
                        }
 
3033
 
 
3034
                        if (prev_adaptive_flushing_method == 2) {
 
3035
                                int32_t         n_flush;
 
3036
                                int32_t         blocks_sum = 0;
 
3037
                                uint32_t        new_blocks_sum = 0;
 
3038
                                uint32_t flushed_blocks_sum = 0;
 
3039
 
 
3040
                                /* prev_flush_info[j] should be the previous loop's */
 
3041
                                for (j = 0; j < srv_buf_pool_instances; j++) {
 
3042
                                        int32_t blocks_num, new_blocks_num, flushed_blocks_num;
 
3043
                                        bool    found = false;
 
3044
 
 
3045
                                        buf_pool = buf_pool_from_array(j);
 
3046
 
 
3047
                                        blocks_num = UT_LIST_GET_LEN(buf_pool->flush_list);
 
3048
                                        bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
 
3049
                                        new_blocks_num = 0;
 
3050
 
 
3051
                                        while (bpage != NULL) {
 
3052
                                                if (prev_flush_info[j].space == bpage->space
 
3053
                                                    && prev_flush_info[j].offset == bpage->offset
 
3054
                                                    && prev_flush_info[j].oldest_modification
 
3055
                                                    == bpage->oldest_modification) {
 
3056
                                                        found = true;
 
3057
                                                        break;
 
3058
                                                }
 
3059
                                                bpage = UT_LIST_GET_NEXT(list, bpage);
 
3060
                                                new_blocks_num++;
 
3061
                                        }
 
3062
                                        if (!found) {
 
3063
                                                new_blocks_num = blocks_num;
 
3064
                                        }
 
3065
                                        flushed_blocks_num = new_blocks_num
 
3066
                                                + prev_flush_info[j].count
 
3067
                                                - blocks_num;
 
3068
                                        if (flushed_blocks_num < 0) {
 
3069
                                                flushed_blocks_num = 0;
 
3070
                                        }
 
3071
 
 
3072
                                        bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
 
3073
 
 
3074
                                        prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
 
3075
                                        if (bpage) {
 
3076
                                                prev_flush_info[j].space = bpage->space;
 
3077
                                                prev_flush_info[j].offset = bpage->offset;
 
3078
                                                prev_flush_info[j].oldest_modification = bpage->oldest_modification;
 
3079
                                        } else {
 
3080
                                                prev_flush_info[j].space = 0;
 
3081
                                                prev_flush_info[j].offset = 0;
 
3082
                                                prev_flush_info[j].oldest_modification = 0;
 
3083
                                        }
 
3084
 
 
3085
                                        new_blocks_sum += new_blocks_num;
 
3086
                                        flushed_blocks_sum += flushed_blocks_num;
 
3087
                                        blocks_sum += blocks_num;
 
3088
                                }
 
3089
 
 
3090
                                n_flush = blocks_sum * (lsn - lsn_old) / log_sys->max_modified_age_async;
 
3091
                                if (flushed_blocks_sum > n_pages_flushed_prev) {
 
3092
                                        n_flush -= (flushed_blocks_sum - n_pages_flushed_prev);
 
3093
                                }
 
3094
 
 
3095
                                if (n_flush > 0) {
 
3096
                                        n_flush++;
 
3097
                                        n_pages_flushed = buf_flush_list(n_flush, oldest_lsn + (lsn - lsn_old));
 
3098
                                } else {
 
3099
                                        n_pages_flushed = 0;
 
3100
                                }
 
3101
                        } else {
 
3102
                                /* store previous first pages of the flush_list */
 
3103
                                for (j = 0; j < srv_buf_pool_instances; j++) {
 
3104
                                        buf_pool = buf_pool_from_array(j);
 
3105
 
 
3106
                                        bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
 
3107
 
 
3108
                                        prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
 
3109
                                        if (bpage) {
 
3110
                                                prev_flush_info[j].space = bpage->space;
 
3111
                                                prev_flush_info[j].offset = bpage->offset;
 
3112
                                                prev_flush_info[j].oldest_modification =  bpage->oldest_modification;
 
3113
                                        } else {
 
3114
                                                prev_flush_info[j].space = 0;
 
3115
                                                prev_flush_info[j].offset = 0;
 
3116
                                                prev_flush_info[j].oldest_modification = 0;
 
3117
                                        }
 
3118
                                }
 
3119
                                n_pages_flushed = 0;
 
3120
                        }
 
3121
 
 
3122
                        lsn_old = lsn;
 
3123
                        prev_adaptive_flushing_method = 2;
 
3124
                } else {
 
3125
                        mutex_enter(&(log_sys->mutex));
 
3126
                        lsn_old = log_sys->lsn;
 
3127
                        mutex_exit(&(log_sys->mutex));
 
3128
                        prev_adaptive_flushing_method = ULINT32_UNDEFINED;
 
3129
                }
 
3130
 
 
3131
                if (n_pages_flushed == ULINT_UNDEFINED) {
 
3132
                        n_pages_flushed_prev = 0;
 
3133
                } else {
 
3134
                        n_pages_flushed_prev = n_pages_flushed;
2762
3135
                }
2763
3136
 
2764
3137
                if (srv_activity_count == old_activity_count) {
2807
3180
        even if the server were active */
2808
3181
 
2809
3182
        srv_main_thread_op_info = "doing insert buffer merge";
2810
 
        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
 
3183
        ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
2811
3184
 
2812
3185
        /* Flush logs if needed */
2813
3186
        srv_sync_log_buffer_in_background();
2885
3258
                MySQL tries to drop a table while there are still open handles
2886
3259
                to it and we had to put it to the background drop queue.) */
2887
3260
 
2888
 
                os_thread_sleep(100000);
 
3261
                if (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
 
3262
                        os_thread_sleep(100000);
 
3263
                }
2889
3264
        }
2890
3265
 
2891
3266
        if (srv_n_purge_threads == 0) {
2913
3288
                buf_flush_list below. Otherwise, the system favors
2914
3289
                clean pages over cleanup throughput. */
2915
3290
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2916
 
                                                           PCT_IO(100));
 
3291
                                                           PCT_IBUF_IO(100));
2917
3292
        }
2918
3293
 
2919
3294
        srv_main_thread_op_info = "reserving kernel mutex";
3044
3419
        goto loop;
3045
3420
 
3046
3421
 
3047
 
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
 
3422
#if !defined(__SUNPRO_C)
3048
3423
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3049
3424
#endif
3050
3425
}
3056
3431
os_thread_ret_t
3057
3432
srv_purge_thread(
3058
3433
/*=============*/
3059
 
        void*   arg __attribute__((unused)))    /*!< in: a dummy parameter
 
3434
        void*   /*arg __attribute__((unused))*/)        /*!< in: a dummy parameter
3060
3435
                                                required by os_thread_create */
3061
3436
{
3062
3437
        srv_slot_t*     slot;
3063
3438
        ulint           slot_no = ULINT_UNDEFINED;
3064
3439
        ulint           n_total_purged = ULINT_UNDEFINED;
 
3440
        ulint           next_itr_time;
3065
3441
 
3066
3442
        ut_a(srv_n_purge_threads == 1);
3067
3443
 
3080
3456
 
3081
3457
        mutex_exit(&kernel_mutex);
3082
3458
 
 
3459
        next_itr_time = ut_time_ms();
 
3460
 
3083
3461
        while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
3084
3462
 
3085
3463
                ulint   n_pages_purged;
 
3464
                ulint   cur_time;
3086
3465
 
3087
3466
                /* If there are very few records to purge or the last
3088
3467
                purge didn't purge any records then wait for activity.
3123
3502
                } while (n_pages_purged > 0 && !srv_fast_shutdown);
3124
3503
 
3125
3504
                srv_sync_log_buffer_in_background();
 
3505
 
 
3506
                cur_time = ut_time_ms();
 
3507
                if (next_itr_time > cur_time) {
 
3508
                        os_thread_sleep(ut_min(1000000,
 
3509
                                               (next_itr_time - cur_time)
 
3510
                                               * 1000));
 
3511
                        next_itr_time = ut_time_ms() + 1000;
 
3512
                } else {
 
3513
                        next_itr_time = cur_time + 1000;
 
3514
                }
3126
3515
        }
3127
3516
 
3128
3517
        mutex_enter(&kernel_mutex);