Compare commits
15 Commits
v4.4.30-ch
...
v4.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ae4c9990d | ||
|
|
2efece39cc | ||
|
|
cb802868a9 | ||
|
|
ec2eddc00c | ||
|
|
ccf485934c | ||
|
|
7b19184fcd | ||
|
|
6a63b7fe22 | ||
|
|
e24a0feb72 | ||
|
|
a8b03f81fa | ||
|
|
722bdbc7cc | ||
|
|
c326c9a2b2 | ||
|
|
ab382cff67 | ||
|
|
6d0568e1ec | ||
|
|
c9638fb418 | ||
|
|
8b0b9b1d69 |
@@ -1,27 +0,0 @@
|
||||
logging:
|
||||
executor:
|
||||
format: '[%(name)s] %(asctime)s %(message)s'
|
||||
handlers:
|
||||
- class: logging.StreamHandler
|
||||
fixture:
|
||||
format: '[%(name)s] %(message)s'
|
||||
handlers:
|
||||
- class: evergreen
|
||||
tests:
|
||||
format: '[%(name)s] %(message)s'
|
||||
handlers:
|
||||
- class: evergreen
|
||||
|
||||
shorten_logger_name:
|
||||
remove:
|
||||
- MongoDFixture
|
||||
- ReplicaSetFixture
|
||||
- ShardedClusterFixture
|
||||
replace:
|
||||
primary: prim
|
||||
secondary: sec
|
||||
node: n
|
||||
shard: s
|
||||
configsvr: c
|
||||
mongos: s
|
||||
job: j
|
||||
@@ -111,7 +111,6 @@ DEFAULTS = {
|
||||
"task_name": None,
|
||||
"variant_name": None,
|
||||
"version_id": None,
|
||||
"work_dir": None,
|
||||
|
||||
# WiredTiger options.
|
||||
"wt_coll_config": None,
|
||||
@@ -287,9 +286,6 @@ EVERGREEN_VARIANT_NAME = None
|
||||
# the commit hash.
|
||||
EVERGREEN_VERSION_ID = None
|
||||
|
||||
# The Evergreen task's working directory.
|
||||
EVERGREEN_WORK_DIR = None
|
||||
|
||||
# If set, then any jstests that have any of the specified tags will be excluded from the suite(s).
|
||||
EXCLUDE_WITH_ANY_TAGS = None
|
||||
|
||||
|
||||
@@ -240,7 +240,6 @@ or explicitly pass --installDir to the run subcommand of buildscripts/resmoke.py
|
||||
_config.EVERGREEN_TASK_NAME = config.pop("task_name")
|
||||
_config.EVERGREEN_VARIANT_NAME = config.pop("variant_name")
|
||||
_config.EVERGREEN_VERSION_ID = config.pop("version_id")
|
||||
_config.EVERGREEN_WORK_DIR = config.pop("work_dir")
|
||||
|
||||
# Archival options. Archival is enabled only when running on evergreen.
|
||||
if not _config.EVERGREEN_TASK_ID:
|
||||
|
||||
@@ -41,17 +41,3 @@ class ISO8601Formatter(logging.Formatter):
|
||||
utc_offset_mins = (utc_offset_secs / 60) % 60
|
||||
utc_offset_hours = utc_offset_secs / 3600
|
||||
return "%s%02d%02d" % (utc_offset_prefix, utc_offset_hours, utc_offset_mins)
|
||||
|
||||
|
||||
class EvergreenLogFormatter(logging.Formatter):
|
||||
"""Log line formatter for Evergreen log messages.
|
||||
|
||||
See `https://docs.devprod.prod.corp.mongodb.com/evergreen/Project-Configuration/Task-Output-Directory#test-logs`
|
||||
for more info.
|
||||
"""
|
||||
|
||||
def format(self, record):
|
||||
"""Return the Evergreen formatted record."""
|
||||
ts = int(record.created * 1e9)
|
||||
|
||||
return "\n".join([f"{ts} {line}" for line in super().format(record).split("\n")])
|
||||
|
||||
@@ -162,29 +162,6 @@ class BufferedHandler(logging.Handler):
|
||||
logging.Handler.close(self)
|
||||
|
||||
|
||||
class BufferedFileHandler(BufferedHandler):
|
||||
"""File handler with in-memory buffering."""
|
||||
|
||||
def __init__(self, filename, capacity=2000, interval_secs=600):
|
||||
"""Initialize the handler with the filename and buffer capacity and flush interval."""
|
||||
super().__init__(capacity, interval_secs)
|
||||
self.file = open(filename, "a")
|
||||
|
||||
def process_record(self, record):
|
||||
"""Return the formatted record message appended with a newline."""
|
||||
return self.format(record) + "\n"
|
||||
|
||||
def _flush_buffer_with_lock(self, buf, close_called):
|
||||
"""Write the buffered log lines to the destination file."""
|
||||
self.file.writelines(buf)
|
||||
|
||||
def close(self):
|
||||
"""Close the handler and the file descriptor."""
|
||||
super().close()
|
||||
|
||||
self.file.close()
|
||||
|
||||
|
||||
class HTTPHandler(object):
|
||||
"""A class which sends data to a web server using POST requests."""
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
"""Module to hold the logger instances themselves."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
from . import buildlogger
|
||||
from . import formatters
|
||||
from . import handlers
|
||||
from .. import config
|
||||
from .. import errors
|
||||
|
||||
_DEFAULT_FORMAT = "[%(name)s] %(message)s"
|
||||
@@ -48,13 +44,6 @@ def configure_loggers(logging_config):
|
||||
EXECUTOR_LOGGER = ExecutorRootLogger(logging_config, build_logger_server, fixture_logger,
|
||||
tests_logger)
|
||||
|
||||
_write_evergreen_log_spec()
|
||||
|
||||
|
||||
def get_evergreen_log_name(job_num, test_id=None):
|
||||
"""Return the log name, relative to the reserved test log directory, on the Evergreen task host."""
|
||||
return f"job{job_num}/" + (f"{test_id}.log" if test_id else "global.log")
|
||||
|
||||
|
||||
class BaseLogger(logging.Logger):
|
||||
"""Base class for the custom loggers used in this library.
|
||||
@@ -138,8 +127,6 @@ class RootLogger(BaseLogger):
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
elif handler_class == "buildlogger":
|
||||
return # Buildlogger handlers are applied when creating specific child loggers
|
||||
elif handler_class == "evergreen":
|
||||
return # Evergreen handlers are applied when creating specific child loggers
|
||||
else:
|
||||
raise ValueError("Unknown handler class '%s'" % handler_class)
|
||||
handler.setFormatter(formatter)
|
||||
@@ -205,46 +192,42 @@ class JobLogger(BaseLogger):
|
||||
"""Create a new fixture logger that will be a child of the "fixture" root logger."""
|
||||
return FixtureLogger(fixture_class, self.job_num, self.build_id, self.fixture_root_logger)
|
||||
|
||||
def new_test_logger(self, test_id, test_shortname, test_basename, command, parent): # pylint: disable=too-many-arguments
|
||||
def new_test_logger(self, test_shortname, test_basename, command, parent):
|
||||
"""Create a new test logger that will be a child of the given parent."""
|
||||
if self.build_id:
|
||||
# If we're configured to log messages to the buildlogger server, then request a new
|
||||
# test id for this test.
|
||||
build_test_id = self.build_logger_server.new_test_id(self.build_id, test_basename,
|
||||
command)
|
||||
if not build_test_id:
|
||||
# test_id for this test.
|
||||
test_id = self.build_logger_server.new_test_id(self.build_id, test_basename, command)
|
||||
if not test_id:
|
||||
buildlogger.set_log_output_incomplete()
|
||||
raise errors.LoggerRuntimeConfigError(
|
||||
"Encountered an error configuring buildlogger for test {}: Failed to get a new"
|
||||
" test_id".format(test_basename))
|
||||
|
||||
url = self.build_logger_server.get_test_log_url(self.build_id, build_test_id)
|
||||
url = self.build_logger_server.get_test_log_url(self.build_id, test_id)
|
||||
self.info("Writing output of %s to %s.", test_basename, url)
|
||||
return TestLogger(test_shortname, parent, self.job_num, self.build_id, build_test_id,
|
||||
url)
|
||||
return TestLogger(test_shortname, parent, self.build_id, test_id, url)
|
||||
|
||||
return TestLogger(test_shortname, parent, job_num=self.job_num, test_id=test_id)
|
||||
return TestLogger(test_shortname, parent)
|
||||
|
||||
|
||||
class TestLogger(BaseLogger):
|
||||
"""TestLogger class."""
|
||||
|
||||
def __init__( # pylint: disable=too-many-arguments
|
||||
self, test_name, parent, job_num=None, build_id=None, test_id=None, url=None):
|
||||
self, test_name, parent, build_id=None, test_id=None, url=None):
|
||||
"""Initialize a TestLogger.
|
||||
|
||||
:param test_name: the test name.
|
||||
:param parent: the parent logger.
|
||||
:param job_num: the number of the job the test is running on.
|
||||
:param build_id: the build logger build id.
|
||||
:param test_id: the test id for the logger handler.
|
||||
:param test_id: the build logger test id.
|
||||
:param url: the build logger URL endpoint for the test.
|
||||
"""
|
||||
name = "%s:%s" % (parent.name, test_name)
|
||||
BaseLogger.__init__(self, name, parent=parent)
|
||||
self.url_endpoint = url
|
||||
self._add_build_logger_handler(build_id, test_id)
|
||||
_add_evergreen_handler(self, self.logging_config, job_num, test_id)
|
||||
|
||||
def _add_build_logger_handler(self, build_id, test_id):
|
||||
logger_info = self.logging_config[TESTS_LOGGER_NAME]
|
||||
@@ -286,7 +269,6 @@ class FixtureLogger(BaseLogger):
|
||||
self.fixture_class = fixture_class
|
||||
self.job_num = job_num
|
||||
self._add_build_logger_handler(build_id)
|
||||
_add_evergreen_handler(self, self.logging_config, job_num)
|
||||
|
||||
def _add_build_logger_handler(self, build_id):
|
||||
logger_info = self.logging_config[FIXTURE_LOGGER_NAME]
|
||||
@@ -388,55 +370,3 @@ def _get_buildlogger_handler_info(logger_info):
|
||||
if handler_info.pop("class") == "buildlogger":
|
||||
return handler_info
|
||||
return None
|
||||
|
||||
|
||||
# Utility functions for Evergreen file system logging.
|
||||
# See `https://docs.devprod.prod.corp.mongodb.com/evergreen/Project-Configuration/Task-Output-Directory#test-logs`
|
||||
# for more information.
|
||||
|
||||
|
||||
def _write_evergreen_log_spec():
|
||||
"""Configure file system logging for Evergreen tasks."""
|
||||
if not config.EVERGREEN_WORK_DIR:
|
||||
return
|
||||
|
||||
fp = f"{_get_evergreen_log_dirname()}/log_spec.yaml"
|
||||
os.makedirs(os.path.dirname(fp), exist_ok=True)
|
||||
|
||||
EXECUTOR_LOGGER.info("Writing Evergreen test log spec to %s.", fp)
|
||||
|
||||
log_spec = {
|
||||
"version": 0,
|
||||
"format": "text-timestamp",
|
||||
}
|
||||
with open(fp, "w") as fd:
|
||||
yaml.dump(log_spec, fd)
|
||||
|
||||
|
||||
def _add_evergreen_handler(logger, logging_config, job_num, test_id=None):
|
||||
"""Add a new evergreen handler to a logger."""
|
||||
logger_info = logging_config[TESTS_LOGGER_NAME]
|
||||
evergreen_handler_info = None
|
||||
for handler_info in logger_info["handlers"]:
|
||||
if handler_info["class"] == "evergreen":
|
||||
evergreen_handler_info = handler_info
|
||||
break
|
||||
|
||||
if evergreen_handler_info:
|
||||
fp = f"{_get_evergreen_log_dirname()}/{get_evergreen_log_name(job_num, test_id)}"
|
||||
os.makedirs(os.path.dirname(fp), exist_ok=True)
|
||||
|
||||
handler = handlers.BufferedFileHandler(fp)
|
||||
handler.setFormatter(
|
||||
formatters.EvergreenLogFormatter(fmt=logger_info.get("format", _DEFAULT_FORMAT)))
|
||||
logger.addHandler(handler)
|
||||
|
||||
if test_id:
|
||||
EXECUTOR_LOGGER.info("Writing output of %s to %s.", test_id, fp)
|
||||
else:
|
||||
EXECUTOR_LOGGER.info("Writing output of job #%d to %s.", job_num, fp)
|
||||
|
||||
|
||||
def _get_evergreen_log_dirname():
|
||||
"""Return the reserved directory for test logs on the Evergreen task host."""
|
||||
return f"{config.EVERGREEN_WORK_DIR}/build/TestLogs"
|
||||
|
||||
@@ -385,9 +385,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
|
||||
evergreen_options.add_argument("--versionId", dest="version_id", metavar="VERSION_ID",
|
||||
help="Sets the version ID of the task.")
|
||||
|
||||
evergreen_options.add_argument("--taskWorkDir", dest="work_dir", metavar="TASK_WORK_DIR",
|
||||
help="Sets the working directory of the task.")
|
||||
|
||||
benchmark_options = parser.add_argument_group(
|
||||
title=_BENCHMARK_ARGUMENT_TITLE, description="Options for running Benchmark/Benchrun tests")
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ This is used to support additional test status and timing information for the re
|
||||
"""
|
||||
|
||||
import copy
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
@@ -99,7 +98,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
|
||||
unittest.TestResult.startTest(self, test)
|
||||
|
||||
test_info = _TestInfo(test.id(), test.test_name, test.dynamic)
|
||||
test_info.group_id = f"job{self.job_logger.job_num}"
|
||||
|
||||
basename = test.basename()
|
||||
command = test.as_command()
|
||||
@@ -114,14 +112,10 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
|
||||
self.num_dynamic += 1
|
||||
|
||||
# Set up the test-specific logger.
|
||||
test_logger = self.job_logger.new_test_logger(test.id(), test.short_name(), test.basename(),
|
||||
command, test.logger)
|
||||
test_logger = self.job_logger.new_test_logger(test.short_name(), test.basename(), command,
|
||||
test.logger)
|
||||
test_info.url_endpoint = test_logger.url_endpoint
|
||||
test_info.log_info = {
|
||||
"log_name": logging.loggers.get_evergreen_log_name(self.job_logger.job_num, test.id()),
|
||||
"logs_to_merge": [logging.loggers.get_evergreen_log_name(self.job_logger.job_num)],
|
||||
"rendering_type": "resmoke", "version": 0
|
||||
}
|
||||
|
||||
test.override_logger(test_logger)
|
||||
test_info.start_time = time.time()
|
||||
|
||||
@@ -268,18 +262,13 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
|
||||
for test_info in self.test_infos:
|
||||
result = {
|
||||
"test_file": test_info.test_file,
|
||||
"group_id": test_info.group_id,
|
||||
"status": test_info.evergreen_status,
|
||||
"exit_code": test_info.return_code,
|
||||
"start": test_info.start_time,
|
||||
"end": test_info.end_time,
|
||||
"elapsed": test_info.end_time - test_info.start_time,
|
||||
"log_info": test_info.log_info,
|
||||
}
|
||||
|
||||
if test_info.display_test_name is not None:
|
||||
result["display_test_name"] = test_info.display_test_name
|
||||
|
||||
if test_info.url_endpoint is not None:
|
||||
result["url"] = test_info.url_endpoint
|
||||
result["url_raw"] = test_info.url_endpoint + "?raw=1"
|
||||
@@ -306,9 +295,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
|
||||
# Using test_file as the test id is ok here since the test id only needs to be unique
|
||||
# during suite execution.
|
||||
test_info = _TestInfo(test_file, test_file, is_dynamic)
|
||||
test_info.display_test_name = result.get("display_test_name")
|
||||
test_info.group_id = result.get("group_id")
|
||||
test_info.log_info = result.get("log_info")
|
||||
test_info.url_endpoint = result.get("url")
|
||||
test_info.status = result["status"]
|
||||
test_info.evergreen_status = test_info.status
|
||||
@@ -362,8 +348,6 @@ class _TestInfo(object): # pylint: disable=too-many-instance-attributes
|
||||
|
||||
self.test_id = test_id
|
||||
self.test_file = test_file
|
||||
self.group_id = None
|
||||
self.display_test_name = None
|
||||
self.dynamic = dynamic
|
||||
|
||||
self.start_time = None
|
||||
@@ -371,7 +355,6 @@ class _TestInfo(object): # pylint: disable=too-many-instance-attributes
|
||||
self.status = None
|
||||
self.evergreen_status = None
|
||||
self.return_code = None
|
||||
self.log_info = None
|
||||
self.url_endpoint = None
|
||||
|
||||
|
||||
|
||||
@@ -1387,11 +1387,11 @@ functions:
|
||||
${san_options} \
|
||||
${snmp_config_path} \
|
||||
${resmoke_wrapper} \
|
||||
$python buildscripts/resmoke.py run \
|
||||
$python buildscripts/resmoke.py run \
|
||||
${resmoke_args} \
|
||||
$extra_args \
|
||||
${test_flags} \
|
||||
--log=${resmoke_logger} \
|
||||
--log=buildlogger \
|
||||
--staggerJobs=on \
|
||||
--installDir=${install_dir|dist-test/bin} \
|
||||
--buildId=${build_id} \
|
||||
@@ -1404,7 +1404,6 @@ functions:
|
||||
--taskName=${task_name} \
|
||||
--variantName=${build_variant} \
|
||||
--versionId=${version_id} \
|
||||
--taskWorkDir='${workdir}' \
|
||||
--archiveFile=archive.json \
|
||||
--reportFile=report.json \
|
||||
--perfReportFile=perf.json
|
||||
@@ -7743,6 +7742,7 @@ tasks:
|
||||
- func: "scons compile"
|
||||
vars:
|
||||
targets: >-
|
||||
distsrc-${ext|tgz}
|
||||
archive-dist
|
||||
archive-dist-debug
|
||||
archive-shell
|
||||
@@ -7763,6 +7763,19 @@ tasks:
|
||||
# Validate that this build_variant is listed as a known enterprise task for mongocryptd
|
||||
PATH=$PATH:$HOME $python ../buildscripts/validate_mongocryptd.py --variant "${build_variant}" ../etc/evergreen.yml
|
||||
fi
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/distsrc.${ext|tgz}
|
||||
remote_file: ${project}/${build_variant}/${revision}/sources/mongo-src-${build_id}.${ext|tgz}
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/gzip}
|
||||
display_name: Source tarball
|
||||
# We only need to upload the source tarball from one of the build variants
|
||||
# because it should be the same everywhere, so just use rhel70/windows.
|
||||
build_variants: [rhel70, windows]
|
||||
- command: s3.put
|
||||
params:
|
||||
optional: true
|
||||
@@ -7950,6 +7963,14 @@ tasks:
|
||||
local_file: src/mh.tgz
|
||||
build_variants: *mh_variants
|
||||
# Fetch the sources (on relevant variants only)
|
||||
- command: s3.get
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
remote_file: ${project}/${build_variant}/${revision}/sources/mongo-src-${build_id}.${ext|tgz}
|
||||
bucket: mciuploads
|
||||
local_file: src/distsrc.${ext|tgz}
|
||||
build_variants: [rhel70, windows]
|
||||
- func: "apply compile expansions"
|
||||
- func: "fetch dist debugsymbols"
|
||||
- func: "set up remote credentials"
|
||||
@@ -7961,7 +7982,6 @@ tasks:
|
||||
- command: shell.exec
|
||||
params:
|
||||
shell: bash
|
||||
silent: true
|
||||
script: |
|
||||
set -oe
|
||||
echo "${release_tools_container_registry_password}" | podman login --password-stdin --username ${release_tools_container_registry_username} ${release_tools_container_registry}
|
||||
@@ -8024,6 +8044,17 @@ tasks:
|
||||
content_type: ${content_type|application/gzip}
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mh-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}
|
||||
build_variants: *mh_variants
|
||||
# Put the source tarball
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}
|
||||
aws_key: ${aws_key}
|
||||
bucket: build-push-testing
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/gzip}
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}
|
||||
build_variants: [rhel70, windows]
|
||||
|
||||
# Put the debug symbols
|
||||
- command: s3.put
|
||||
@@ -8071,6 +8102,18 @@ tasks:
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sig
|
||||
build_variants: *mongocryptd_variants
|
||||
|
||||
# Put the source tarball signature
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sig
|
||||
aws_key: ${aws_key}
|
||||
bucket: build-push-testing
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/gzip}
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sig
|
||||
build_variants: [rhel70, windows]
|
||||
|
||||
# Put the debug symbols signature
|
||||
- command: s3.put
|
||||
params:
|
||||
@@ -8129,6 +8172,18 @@ tasks:
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha1
|
||||
build_variants: *mongocryptd_variants
|
||||
|
||||
# Put the source tarball sha1
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha1
|
||||
aws_key: ${aws_key}
|
||||
permissions: public-read
|
||||
bucket: build-push-testing
|
||||
content_type: text/plain
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha1
|
||||
build_variants: [rhel70, windows]
|
||||
|
||||
# Put the debug symbols sha1
|
||||
- command: s3.put
|
||||
params:
|
||||
@@ -8187,6 +8242,18 @@ tasks:
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha256
|
||||
build_variants: *mongocryptd_variants
|
||||
|
||||
# Put the source tarball sha256
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha256
|
||||
permissions: public-read
|
||||
aws_key: ${aws_key}
|
||||
bucket: build-push-testing
|
||||
content_type: text/plain
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha256
|
||||
build_variants: [rhel70, windows]
|
||||
|
||||
# Put the debug symbols sha256
|
||||
- command: s3.put
|
||||
params:
|
||||
@@ -8245,6 +8312,18 @@ tasks:
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.md5
|
||||
build_variants: *mongocryptd_variants
|
||||
|
||||
# Put the source tarball md5
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb-src-${src_suffix}.${ext|tar.gz}.md5
|
||||
aws_key: ${aws_key}
|
||||
bucket: build-push-testing
|
||||
permissions: public-read
|
||||
content_type: text/plain
|
||||
remote_file: ${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.md5
|
||||
build_variants: [rhel70, windows]
|
||||
|
||||
# Put the debug symbols md5
|
||||
- command: s3.put
|
||||
params:
|
||||
@@ -8292,6 +8371,11 @@ tasks:
|
||||
'destination': {'path': '${push_path}/mh-${push_name}-${push_arch}-${suffix}.${ext|tgz}', 'bucket': '${push_bucket}'},
|
||||
'build_variants': *mh_variants}
|
||||
|
||||
#Source tarball
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}', 'bucket': '${push_bucket}'},
|
||||
'build_variants': ['rhel70', 'windows']}
|
||||
|
||||
#MSI (Windows only)
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi', 'bucket': '${push_bucket}'},
|
||||
@@ -8310,6 +8394,11 @@ tasks:
|
||||
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sig', 'bucket': '${push_bucket}'},
|
||||
'build_variants': *mongocryptd_variants}
|
||||
|
||||
#Source tarball signature
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sig', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sig', 'bucket': '${push_bucket}'},
|
||||
'build_variants': ['rhel70', 'windows']}
|
||||
|
||||
#SHA1 for binaries
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}.${ext|tgz}.sha1', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha1', 'bucket': '${push_bucket}'}}
|
||||
@@ -8323,6 +8412,11 @@ tasks:
|
||||
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha1', 'bucket': '${push_bucket}'},
|
||||
'build_variants': *mongocryptd_variants}
|
||||
|
||||
#SHA1 for source tarball
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha1', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha1', 'bucket': '${push_bucket}'},
|
||||
'build_variants': ['rhel70', 'windows']}
|
||||
|
||||
#SHA1 for MSI
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.sha1', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.sha1', 'bucket': '${push_bucket}'},
|
||||
@@ -8341,6 +8435,11 @@ tasks:
|
||||
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.sha256', 'bucket': '${push_bucket}'},
|
||||
'build_variants': *mongocryptd_variants}
|
||||
|
||||
#SHA256 for source tarball
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.sha256', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.sha256', 'bucket': '${push_bucket}'},
|
||||
'build_variants': ['rhel70', 'windows']}
|
||||
|
||||
#SHA256 for MSI files
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.sha256', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.sha256', 'bucket': '${push_bucket}'},
|
||||
@@ -8359,6 +8458,11 @@ tasks:
|
||||
'destination': {'path': '${push_path}/mongodb-cryptd-${push_name}-${push_arch}-${suffix}.${ext|tgz}.md5', 'bucket': '${push_bucket}'},
|
||||
'build_variants': *mongocryptd_variants}
|
||||
|
||||
#MD5 for source tarball
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-src-${src_suffix}-${task_id}.${ext|tar.gz}.md5', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': 'src/mongodb-src-${src_suffix}.${ext|tar.gz}.md5', 'bucket': '${push_bucket}'},
|
||||
'build_variants': ['rhel70', 'windows']}
|
||||
|
||||
#MD5 for MSIs
|
||||
- {'source': {'path': '${push_path}-STAGE/${push_name}/mongodb-${push_name}-${push_arch}-${suffix}-${task_id}-signed.msi.md5', 'bucket': 'build-push-testing'},
|
||||
'destination': {'path': '${push_path}/mongodb-${push_name}-${push_arch}-${suffix}-signed.msi.md5', 'bucket': '${push_bucket}'},
|
||||
@@ -9978,16 +10082,33 @@ buildvariants:
|
||||
test_flags: --excludeWithAnyTags=requires_increased_memlock_limits --enableEnterpriseTests=off
|
||||
tasks:
|
||||
- name: compile_all_run_unittests_TG
|
||||
- name: aggregation
|
||||
- name: .aggregation !.auth !.encrypt !.unwind
|
||||
- name: .auth .gle
|
||||
- name: auth_gen
|
||||
- name: .causally_consistent !.sharding
|
||||
- name: .change_streams !.secondary_reads
|
||||
- name: .misc_js
|
||||
- name: .concurrency !.ubsan !.no_txns !.debug_only !.kill_terminate
|
||||
- name: disk_wiredtiger
|
||||
- name: .jscore .common !.auth !.sharding
|
||||
- name: initial_sync_fuzzer_gen
|
||||
- name: .jscore .common !.auth
|
||||
- name: .jstestfuzz .causal
|
||||
- name: .jstestfuzz .interrupt
|
||||
- name: .jstestfuzz .common
|
||||
- name: .jstestfuzz .session
|
||||
- name: .logical_session_cache .one_sec
|
||||
- name: .query_fuzzer
|
||||
- name: .read_write_concern !.linearize
|
||||
- name: replica_sets
|
||||
- name: replica_sets_kill_secondaries_jscore_passthrough
|
||||
- name: .replica_sets .common !.auth
|
||||
- name: retryable_writes_jscore_passthrough_gen
|
||||
- name: .rollbackfuzzer
|
||||
- name: session_jscore_passthrough
|
||||
- name: .sharding .jscore !.wo_snapshot !.multi_stmt
|
||||
- name: .sharding .txns
|
||||
- name: .ssl
|
||||
- name: .stitch
|
||||
- name: push
|
||||
|
||||
- name: macos-debug
|
||||
@@ -10005,12 +10126,16 @@ buildvariants:
|
||||
- name: compile_build_tools_next_TG
|
||||
- name: aggregation
|
||||
- name: auth_gen
|
||||
- name: causally_consistent_jscore_txns_passthrough
|
||||
- name: disk_wiredtiger
|
||||
- name: failpoints
|
||||
- name: .jscore .common !.auth !.sharding
|
||||
- name: jsCore_txns_large_txns_format
|
||||
- name: mongosTest
|
||||
- name: replica_sets
|
||||
- name: replica_sets_large_txns_format_gen
|
||||
- name: .ssl
|
||||
- name: .stitch
|
||||
|
||||
- name: enterprise-macos
|
||||
display_name: Enterprise macOS
|
||||
@@ -10030,10 +10155,14 @@ buildvariants:
|
||||
- name: compile_ninja_next_TG
|
||||
- name: audit
|
||||
- name: auth_audit_gen
|
||||
- name: causally_consistent_jscore_txns_passthrough
|
||||
- name: .encrypt !.replica_sets !.sharding !.aggregation !.jscore
|
||||
- name: .jscore .common !.compat !.decimal !.sharding
|
||||
- name: .jstestfuzz .common
|
||||
- name: .logical_session_cache .one_sec
|
||||
- name: mqlrun
|
||||
- name: replica_sets_auth_gen
|
||||
- name: replica_sets_jscore_passthrough
|
||||
- name: sasl
|
||||
- name: push
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ modules:
|
||||
prefix: ${workdir}/src
|
||||
branch: master
|
||||
- name: genny
|
||||
owner: mongodb
|
||||
owner: 10gen
|
||||
repo: genny
|
||||
prefix: ${workdir}/src
|
||||
branch: master
|
||||
|
||||
@@ -14,7 +14,7 @@ cat << 'EOF' > jsign_signing_commands.sh
|
||||
function sign(){
|
||||
if [ -e $1 ]
|
||||
then
|
||||
jsign -a mongo-authenticode-2021 --replace --tsaurl http://timestamp.digicert.com -d SHA-256 $1
|
||||
jsign -a mongo-authenticode-2024 --replace --tsaurl http://timestamp.digicert.com -d SHA-256 $1
|
||||
else
|
||||
echo "$1 does not exist. Skipping signing"
|
||||
fi
|
||||
|
||||
@@ -167,6 +167,26 @@ void checkOverflow(std::unique_ptr<MessageCompressorBase> compressor) {
|
||||
compressor->decompressData(tooSmallRange, DataRange(scratch.data(), scratch.size())));
|
||||
}
|
||||
|
||||
void checkUndersize(const Message& compressedMsg,
|
||||
std::unique_ptr<MessageCompressorBase> compressor) {
|
||||
MessageCompressorRegistry registry;
|
||||
const auto compressorName = compressor->getName();
|
||||
|
||||
std::vector<std::string> compressorList = {compressorName};
|
||||
registry.setSupportedCompressors(std::move(compressorList));
|
||||
registry.registerImplementation(std::move(compressor));
|
||||
registry.finalizeSupportedCompressors().transitional_ignore();
|
||||
|
||||
MessageCompressorManager mgr(®istry);
|
||||
BSONObjBuilder negotiatorOut;
|
||||
auto negotiator = BSON("isMaster" << 1 << "compression" << BSON_ARRAY(compressorName));
|
||||
mgr.serverNegotiate(negotiator, &negotiatorOut);
|
||||
checkNegotiationResult(negotiatorOut.done(), {compressorName});
|
||||
|
||||
auto swm = mgr.decompressMessage(compressedMsg);
|
||||
ASSERT_EQ(ErrorCodes::BadValue, swm.getStatus());
|
||||
}
|
||||
|
||||
Message buildMessage() {
|
||||
const auto data = std::string{"Hello, world!"};
|
||||
const auto bufferSize = MsgData::MsgDataHeaderSize + data.size();
|
||||
@@ -252,6 +272,52 @@ TEST(ZstdMessageCompressor, Overflow) {
|
||||
checkOverflow(std::make_unique<ZstdMessageCompressor>());
|
||||
}
|
||||
|
||||
TEST(ZlibMessageCompressor, Mismatch) {
|
||||
checkOverflow(std::make_unique<ZlibMessageCompressor>());
|
||||
}
|
||||
|
||||
TEST(SnappyMessageCompressor, Undersize) {
|
||||
std::vector<std::uint8_t> payload = {
|
||||
0x41, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc,
|
||||
0x7, 0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x1, 0x27,
|
||||
0x0, 0x0, 0x1, 0x1, 0x84, 0xfb, 0x1f, 0x0, 0x0, 0x5, 0x5f, 0x69, 0x64,
|
||||
0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45, 0x41, 0x50, 0x4c, 0x45, 0x41,
|
||||
0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
|
||||
|
||||
auto buffer = SharedBuffer::allocate(payload.size());
|
||||
std::copy(payload.begin(), payload.end(), buffer.get());
|
||||
|
||||
checkUndersize(Message(buffer), std::make_unique<SnappyMessageCompressor>());
|
||||
}
|
||||
|
||||
TEST(ZlibMessageCompressor, Undersize) {
|
||||
std::vector<std::uint8_t> payload = {
|
||||
0x3c, 0x00, 0x00, 0x00, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00,
|
||||
0x00, 0xdd, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x78, 0xda, 0x63, 0x60, 0x00,
|
||||
0x82, 0xdf, 0xf2, 0x0c, 0x0c, 0xac, 0xf1, 0x99, 0x29, 0x0c, 0x0c, 0x02, 0x40, 0x9e, 0x87,
|
||||
0xab, 0x63, 0x80, 0x8f, 0xab, 0xa3, 0x37, 0x03, 0x12, 0x00, 0x00, 0x6d, 0x26, 0x04, 0x97};
|
||||
|
||||
auto buffer = SharedBuffer::allocate(payload.size());
|
||||
std::copy(payload.begin(), payload.end(), buffer.get());
|
||||
|
||||
checkUndersize(Message(buffer), std::make_unique<ZlibMessageCompressor>());
|
||||
}
|
||||
|
||||
TEST(ZstdMessageCompressor, Undersize) {
|
||||
std::vector<std::uint8_t> payload = {
|
||||
0x44, 0x0, 0x0, 0x0, 0xad, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, 0x7,
|
||||
0x0, 0x0, 0xdd, 0x7, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x3, 0x28, 0xb5, 0x2f,
|
||||
0xfd, 0x20, 0x27, 0x15, 0x1, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfb, 0x1f,
|
||||
0x0, 0x0, 0x5, 0x5f, 0x69, 0x64, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x48, 0x45,
|
||||
0x41, 0x50, 0x4c, 0x45, 0x41, 0x4b, 0x0, 0x1, 0x0, 0x18, 0xc0, 0x9};
|
||||
|
||||
auto buffer = SharedBuffer::allocate(payload.size());
|
||||
std::copy(payload.begin(), payload.end(), buffer.get());
|
||||
|
||||
checkUndersize(Message(buffer), std::make_unique<ZstdMessageCompressor>());
|
||||
}
|
||||
|
||||
TEST(MessageCompressorManager, SERVER_28008) {
|
||||
|
||||
// Create a client and server that will negotiate the same compressors,
|
||||
|
||||
@@ -74,7 +74,7 @@ StatusWith<std::size_t> ZlibMessageCompressor::decompressData(ConstDataRange inp
|
||||
}
|
||||
|
||||
counterHitDecompress(input.length(), output.length());
|
||||
return {output.length()};
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
#include "mongo/util/fail_point.h"
|
||||
#include "mongo/util/net/socket_exception.h"
|
||||
#include "mongo/util/quick_exit.h"
|
||||
#include "mongo/util/testing_proctor.h"
|
||||
|
||||
namespace mongo {
|
||||
namespace {
|
||||
@@ -493,14 +492,7 @@ void ServiceStateMachine::_processMessage(ThreadGuard guard) {
|
||||
// Format our response, if we have one
|
||||
Message& toSink = dbresponse.response;
|
||||
if (!toSink.empty()) {
|
||||
if (MONGO_unlikely(OpMsg::isFlagSet(_inMessage, OpMsg::kMoreToCome))) {
|
||||
Status error = Status(ErrorCodes::InternalError,
|
||||
"Attempted to respond to fire-and-forget request");
|
||||
if (MONGO_unlikely(TestingProctor::instance().isEnabled())) {
|
||||
invariant(error);
|
||||
}
|
||||
internalAssert(error);
|
||||
}
|
||||
invariant(!OpMsg::isFlagSet(_inMessage, OpMsg::kMoreToCome));
|
||||
invariant(!OpMsg::isFlagSet(toSink, OpMsg::kChecksumPresent));
|
||||
|
||||
// Update the header for the response message.
|
||||
|
||||
14
src/third_party/wiredtiger/dist/api_data.py
vendored
14
src/third_party/wiredtiger/dist/api_data.py
vendored
@@ -689,20 +689,6 @@ connection_runtime_config = [
|
||||
interval in seconds at which to check for files that are
|
||||
inactive and close them''', min=1, max=100000),
|
||||
]),
|
||||
Config('heuristic_controls', '', r'''
|
||||
control the behavior of various optimizations. This is primarily used as a mechanism for
|
||||
rolling out changes to internal heuristics while providing a mechanism for quickly
|
||||
reverting to prior behavior in the field''',
|
||||
type='category', subconfig=[
|
||||
Config('obsolete_tw_btree_max', '100', r'''
|
||||
maximum number of btrees that can be checked for obsolete time window cleanup in a
|
||||
single checkpoint''',
|
||||
min=0, max=500000),
|
||||
Config('obsolete_tw_pages_dirty_max', '100', r'''
|
||||
maximum number of pages that can be marked dirty because of obsolete time window
|
||||
information per btree in a single checkpoint''',
|
||||
min=0, max=100000),
|
||||
]),
|
||||
Config('io_capacity', '', r'''
|
||||
control how many bytes per second are written and read. Exceeding
|
||||
the capacity results in throttling.''',
|
||||
|
||||
1
src/third_party/wiredtiger/dist/stat_data.py
vendored
1
src/third_party/wiredtiger/dist/stat_data.py
vendored
@@ -785,7 +785,6 @@ conn_dsrc_stats = [
|
||||
CacheStat('cache_eviction_clean', 'unmodified pages evicted'),
|
||||
CacheStat('cache_eviction_deepen', 'page split during eviction deepened the tree'),
|
||||
CacheStat('cache_eviction_dirty', 'modified pages evicted'),
|
||||
CacheStat('cache_eviction_dirty_obsolete_tw', 'pages dirtied due to obsolete time window'),
|
||||
CacheStat('cache_eviction_hazard', 'hazard pointer blocked page eviction'),
|
||||
CacheStat('cache_eviction_internal', 'internal pages evicted'),
|
||||
CacheStat('cache_eviction_pages_seen', 'pages seen by eviction walk'),
|
||||
|
||||
2
src/third_party/wiredtiger/import.data
vendored
2
src/third_party/wiredtiger/import.data
vendored
@@ -2,5 +2,5 @@
|
||||
"vendor": "wiredtiger",
|
||||
"github": "wiredtiger/wiredtiger.git",
|
||||
"branch": "mongodb-4.4",
|
||||
"commit": "002ce30f6845d6d070252a5b014168f7265a9448"
|
||||
"commit": "d79240a8f58d3b3b4f92dd4151a54f9133f540cb"
|
||||
}
|
||||
|
||||
@@ -544,12 +544,6 @@ __wt_sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop)
|
||||
btree->syncing = WT_BTREE_SYNC_WAIT;
|
||||
__wt_gen_next_drain(session, WT_GEN_EVICT);
|
||||
btree->syncing = WT_BTREE_SYNC_RUNNING;
|
||||
|
||||
/*
|
||||
* Reset the number of obsolete time window pages to let the eviction threads continue
|
||||
* marking the clean obsolete time window pages as dirty once the checkpoint is finished.
|
||||
*/
|
||||
btree->obsolete_tw_pages = 0;
|
||||
is_hs = WT_IS_HS(btree->dhandle);
|
||||
|
||||
/* Add in history store reconciliation for standard files. */
|
||||
|
||||
@@ -61,11 +61,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_file_manager_subconfigs[] =
|
||||
{"close_scan_interval", "int", NULL, "min=1,max=100000", NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}};
|
||||
|
||||
static const WT_CONFIG_CHECK confchk_wiredtiger_open_heuristic_controls_subconfigs[] = {
|
||||
{"obsolete_tw_btree_max", "int", NULL, "min=0,max=500000", NULL, 0},
|
||||
{"obsolete_tw_pages_dirty_max", "int", NULL, "min=0,max=100000", NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}};
|
||||
|
||||
static const WT_CONFIG_CHECK confchk_wiredtiger_open_history_store_subconfigs[] = {
|
||||
{"file_max", "int", NULL, "min=0", NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0}};
|
||||
|
||||
@@ -122,8 +117,6 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = {
|
||||
{"eviction_updates_target", "int", NULL, "min=0,max=10TB", NULL, 0},
|
||||
{"eviction_updates_trigger", "int", NULL, "min=0,max=10TB", NULL, 0},
|
||||
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
|
||||
{"heuristic_controls", "category", NULL, NULL,
|
||||
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
|
||||
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
|
||||
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
|
||||
{"log", "category", NULL, NULL, confchk_WT_CONNECTION_reconfigure_log_subconfigs, 4},
|
||||
@@ -848,8 +841,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
|
||||
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
|
||||
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
|
||||
{"hazard_max", "int", NULL, "min=15", NULL, 0},
|
||||
{"heuristic_controls", "category", NULL, NULL,
|
||||
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
|
||||
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
|
||||
{"in_memory", "boolean", NULL, NULL, NULL, 0},
|
||||
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
|
||||
@@ -931,8 +922,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
|
||||
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
|
||||
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
|
||||
{"hazard_max", "int", NULL, "min=15", NULL, 0},
|
||||
{"heuristic_controls", "category", NULL, NULL,
|
||||
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
|
||||
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
|
||||
{"in_memory", "boolean", NULL, NULL, NULL, 0},
|
||||
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
|
||||
@@ -1012,8 +1001,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = {
|
||||
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
|
||||
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
|
||||
{"hazard_max", "int", NULL, "min=15", NULL, 0},
|
||||
{"heuristic_controls", "category", NULL, NULL,
|
||||
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
|
||||
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
|
||||
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
|
||||
{"log", "category", NULL, NULL, confchk_wiredtiger_open_log_subconfigs, 10},
|
||||
@@ -1090,8 +1077,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = {
|
||||
{"file_manager", "category", NULL, NULL, confchk_wiredtiger_open_file_manager_subconfigs, 3},
|
||||
{"hash", "category", NULL, NULL, confchk_wiredtiger_open_hash_subconfigs, 2},
|
||||
{"hazard_max", "int", NULL, "min=15", NULL, 0},
|
||||
{"heuristic_controls", "category", NULL, NULL,
|
||||
confchk_wiredtiger_open_heuristic_controls_subconfigs, 2},
|
||||
{"history_store", "category", NULL, NULL, confchk_wiredtiger_open_history_store_subconfigs, 1},
|
||||
{"io_capacity", "category", NULL, NULL, confchk_wiredtiger_open_io_capacity_subconfigs, 1},
|
||||
{"log", "category", NULL, NULL, confchk_wiredtiger_open_log_subconfigs, 10},
|
||||
@@ -1169,9 +1154,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"eviction_dirty_trigger=20,eviction_target=80,eviction_trigger=95"
|
||||
",eviction_updates_target=0,eviction_updates_trigger=0,"
|
||||
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
|
||||
"close_scan_interval=10),"
|
||||
"heuristic_controls=(obsolete_tw_btree_max=100,"
|
||||
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
|
||||
"close_scan_interval=10),history_store=(file_max=0),"
|
||||
"io_capacity=(total=0),log=(archive=true,os_cache_dirty_pct=0,"
|
||||
"prealloc=true,zero_fill=false),lsm_manager=(merge=true,"
|
||||
"worker_thread_max=4),operation_timeout_ms=0,"
|
||||
@@ -1182,7 +1165,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"tiered_manager=(threads_max=8,threads_min=1,wait=0),"
|
||||
"tiered_storage=(local_retention=300),timing_stress_for_test=,"
|
||||
"verbose=[]",
|
||||
confchk_WT_CONNECTION_reconfigure, 30},
|
||||
confchk_WT_CONNECTION_reconfigure, 29},
|
||||
{"WT_CONNECTION.rollback_to_stable", "", NULL, 0}, {"WT_CONNECTION.set_file_system", "", NULL, 0},
|
||||
{"WT_CONNECTION.set_timestamp",
|
||||
"commit_timestamp=,durable_timestamp=,force=false,"
|
||||
@@ -1442,10 +1425,9 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"exclusive=false,extensions=,file_close_sync=true,file_extend=,"
|
||||
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
|
||||
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
|
||||
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
|
||||
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
|
||||
"in_memory=false,io_capacity=(total=0),log=(archive=true,"
|
||||
"compressor=,enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"hazard_max=1000,history_store=(file_max=0),in_memory=false,"
|
||||
"io_capacity=(total=0),log=(archive=true,compressor=,"
|
||||
"enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
|
||||
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
|
||||
"mmap=true,mmap_all=false,multiprocess=false,"
|
||||
@@ -1461,7 +1443,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"timing_stress_for_test=,transaction_sync=(enabled=false,"
|
||||
"method=fsync),use_environment=true,use_environment_priv=false,"
|
||||
"verbose=[],verify_metadata=false,write_through=",
|
||||
confchk_wiredtiger_open, 58},
|
||||
confchk_wiredtiger_open, 57},
|
||||
{"wiredtiger_open_all",
|
||||
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
|
||||
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
|
||||
@@ -1479,10 +1461,9 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"exclusive=false,extensions=,file_close_sync=true,file_extend=,"
|
||||
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
|
||||
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
|
||||
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
|
||||
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
|
||||
"in_memory=false,io_capacity=(total=0),log=(archive=true,"
|
||||
"compressor=,enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"hazard_max=1000,history_store=(file_max=0),in_memory=false,"
|
||||
"io_capacity=(total=0),log=(archive=true,compressor=,"
|
||||
"enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
|
||||
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
|
||||
"mmap=true,mmap_all=false,multiprocess=false,"
|
||||
@@ -1499,7 +1480,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"method=fsync),use_environment=true,use_environment_priv=false,"
|
||||
"verbose=[],verify_metadata=false,version=(major=0,minor=0),"
|
||||
"write_through=",
|
||||
confchk_wiredtiger_open_all, 59},
|
||||
confchk_wiredtiger_open_all, 58},
|
||||
{"wiredtiger_open_basecfg",
|
||||
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
|
||||
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
|
||||
@@ -1517,14 +1498,12 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"extensions=,file_close_sync=true,file_extend=,"
|
||||
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
|
||||
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
|
||||
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
|
||||
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
|
||||
"io_capacity=(total=0),log=(archive=true,compressor=,"
|
||||
"enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
|
||||
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
|
||||
"mmap=true,mmap_all=false,multiprocess=false,"
|
||||
"operation_timeout_ms=0,operation_tracking=(enabled=false,"
|
||||
"hazard_max=1000,history_store=(file_max=0),io_capacity=(total=0)"
|
||||
",log=(archive=true,compressor=,enabled=false,file_max=100MB,"
|
||||
"force_write_wait=0,os_cache_dirty_pct=0,path=\".\",prealloc=true"
|
||||
",recover=on,zero_fill=false),lsm_manager=(merge=true,"
|
||||
"worker_thread_max=4),mmap=true,mmap_all=false,multiprocess=false"
|
||||
",operation_timeout_ms=0,operation_tracking=(enabled=false,"
|
||||
"path=\".\"),readonly=false,salvage=false,session_max=100,"
|
||||
"session_scratch_max=2MB,session_table_cache=true,"
|
||||
"shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB),"
|
||||
@@ -1536,7 +1515,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"timing_stress_for_test=,transaction_sync=(enabled=false,"
|
||||
"method=fsync),verbose=[],verify_metadata=false,version=(major=0,"
|
||||
"minor=0),write_through=",
|
||||
confchk_wiredtiger_open_basecfg, 53},
|
||||
confchk_wiredtiger_open_basecfg, 52},
|
||||
{"wiredtiger_open_usercfg",
|
||||
"buffer_alignment=-1,builtin_extension_config=,cache_cursors=true"
|
||||
",cache_max_wait_ms=0,cache_overhead=8,cache_size=100MB,"
|
||||
@@ -1554,14 +1533,12 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"extensions=,file_close_sync=true,file_extend=,"
|
||||
"file_manager=(close_handle_minimum=250,close_idle_time=30,"
|
||||
"close_scan_interval=10),hash=(buckets=512,dhandle_buckets=512),"
|
||||
"hazard_max=1000,heuristic_controls=(obsolete_tw_btree_max=100,"
|
||||
"obsolete_tw_pages_dirty_max=100),history_store=(file_max=0),"
|
||||
"io_capacity=(total=0),log=(archive=true,compressor=,"
|
||||
"enabled=false,file_max=100MB,force_write_wait=0,"
|
||||
"os_cache_dirty_pct=0,path=\".\",prealloc=true,recover=on,"
|
||||
"zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4),"
|
||||
"mmap=true,mmap_all=false,multiprocess=false,"
|
||||
"operation_timeout_ms=0,operation_tracking=(enabled=false,"
|
||||
"hazard_max=1000,history_store=(file_max=0),io_capacity=(total=0)"
|
||||
",log=(archive=true,compressor=,enabled=false,file_max=100MB,"
|
||||
"force_write_wait=0,os_cache_dirty_pct=0,path=\".\",prealloc=true"
|
||||
",recover=on,zero_fill=false),lsm_manager=(merge=true,"
|
||||
"worker_thread_max=4),mmap=true,mmap_all=false,multiprocess=false"
|
||||
",operation_timeout_ms=0,operation_tracking=(enabled=false,"
|
||||
"path=\".\"),readonly=false,salvage=false,session_max=100,"
|
||||
"session_scratch_max=2MB,session_table_cache=true,"
|
||||
"shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB),"
|
||||
@@ -1572,7 +1549,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {{"WT_CONNECTION.add_collator",
|
||||
"cache_directory=,local_retention=300,name=),"
|
||||
"timing_stress_for_test=,transaction_sync=(enabled=false,"
|
||||
"method=fsync),verbose=[],verify_metadata=false,write_through=",
|
||||
confchk_wiredtiger_open_usercfg, 52},
|
||||
confchk_wiredtiger_open_usercfg, 51},
|
||||
{NULL, NULL, NULL, 0}};
|
||||
|
||||
int
|
||||
|
||||
23
src/third_party/wiredtiger/src/conn/conn_api.c
vendored
23
src/third_party/wiredtiger/src/conn/conn_api.c
vendored
@@ -1982,26 +1982,6 @@ __wt_debug_mode_config(WT_SESSION_IMPL *session, const char *cfg[])
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_heuristic_controls_config --
|
||||
* Set heuristic_controls configuration.
|
||||
*/
|
||||
int
|
||||
__wt_heuristic_controls_config(WT_SESSION_IMPL *session, const char *cfg[])
|
||||
{
|
||||
WT_CONFIG_ITEM cval;
|
||||
WT_CONNECTION_IMPL *conn;
|
||||
|
||||
conn = S2C(session);
|
||||
|
||||
WT_RET(__wt_config_gets(session, cfg, "heuristic_controls.obsolete_tw_btree_max", &cval));
|
||||
conn->heuristic_controls.obsolete_tw_btree_max = (uint32_t)cval.val;
|
||||
WT_RET(__wt_config_gets(session, cfg, "heuristic_controls.obsolete_tw_pages_dirty_max", &cval));
|
||||
conn->heuristic_controls.obsolete_tw_pages_dirty_max = (uint32_t)cval.val;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_verbose_config --
|
||||
* Set verbose configuration.
|
||||
@@ -2854,9 +2834,6 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, const char *c
|
||||
*/
|
||||
WT_ERR(__wt_debug_mode_config(session, cfg));
|
||||
|
||||
/* Parse the heuristic_controls configuration. */
|
||||
WT_ERR(__wt_heuristic_controls_config(session, cfg));
|
||||
|
||||
/*
|
||||
* Load the extensions after initialization completes; extensions expect everything else to be
|
||||
* in place, and the extensions call back into the library.
|
||||
|
||||
@@ -422,7 +422,6 @@ __wt_conn_reconfig(WT_SESSION_IMPL *session, const char **cfg)
|
||||
WT_ERR(__wt_capacity_server_create(session, cfg));
|
||||
WT_ERR(__wt_checkpoint_server_create(session, cfg));
|
||||
WT_ERR(__wt_debug_mode_config(session, cfg));
|
||||
WT_ERR(__wt_heuristic_controls_config(session, cfg));
|
||||
WT_ERR(__wt_hs_config(session, cfg));
|
||||
WT_ERR(__wt_logmgr_reconfig(session, cfg));
|
||||
WT_ERR(__wt_lsm_manager_reconfig(session, cfg));
|
||||
|
||||
116
src/third_party/wiredtiger/src/evict/evict_page.c
vendored
116
src/third_party/wiredtiger/src/evict/evict_page.c
vendored
@@ -557,119 +557,6 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __evict_review_obsolete_time_window --
|
||||
* Check whether the ref has obsolete time window information and mark it for dirty eviction to
|
||||
* remove those obsolete data. An exclusive lock on the page has already been obtained by the
|
||||
* caller.
|
||||
*/
|
||||
static int
|
||||
__evict_review_obsolete_time_window(WT_SESSION_IMPL *session, WT_REF *ref)
|
||||
{
|
||||
WT_ADDR_COPY addr;
|
||||
WT_BTREE *btree;
|
||||
WT_CONNECTION_IMPL *conn;
|
||||
WT_MULTI *multi;
|
||||
WT_PAGE_MODIFY *mod;
|
||||
WT_TIME_AGGREGATE newest_ta;
|
||||
wt_timestamp_t max_durable_ts;
|
||||
uint32_t i;
|
||||
char time_string[WT_TIME_STRING_SIZE];
|
||||
|
||||
btree = S2BT(session);
|
||||
conn = S2C(session);
|
||||
|
||||
/* Too many pages have been cleaned for this btree. */
|
||||
if (btree->obsolete_tw_pages >= conn->heuristic_controls.obsolete_tw_pages_dirty_max)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Pages that the application threads are evicting should not be included. Reconciliation must
|
||||
* be performed when converting a clean page to a dirty page, which can increase latency.
|
||||
*/
|
||||
if (!F_ISSET(session, WT_SESSION_EVICTION))
|
||||
return (0);
|
||||
|
||||
/* Do not perform any obsolete time window cleanup during the startup or shutdown phase. */
|
||||
if (F_ISSET(conn, WT_CONN_RECOVERING | WT_CONN_CLOSING_CHECKPOINT))
|
||||
return (0);
|
||||
|
||||
/* If the file is being checkpointed, other threads can't evict dirty pages. */
|
||||
if (__wt_btree_syncing_by_other_session(session))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Rewriting internal pages doesn't clean the obsolete time window until the leaf pages are
|
||||
* cleared from the obsolete time window.
|
||||
*/
|
||||
WT_ASSERT(session, ref->page != NULL);
|
||||
if (WT_PAGE_IS_INTERNAL(ref->page))
|
||||
return (0);
|
||||
|
||||
/* We are only interested in clean pages. */
|
||||
if (__wt_page_is_modified(ref->page))
|
||||
return (0);
|
||||
|
||||
/* Limit the number of btrees that can be cleaned up. */
|
||||
if (btree->obsolete_tw_pages == 0 &&
|
||||
conn->heuristic_controls.obsolete_tw_btree_count >=
|
||||
conn->heuristic_controls.obsolete_tw_btree_max)
|
||||
return (0);
|
||||
|
||||
/* Don't add more cache pressure. */
|
||||
if (__wt_eviction_needed(session, false, false, NULL) || __wt_cache_stuck(session))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Initialize the time aggregate via the merge initialization, so that stop visibility is copied
|
||||
* across correctly. That is why we need the stop timestamp/transaction IDs to start as none,
|
||||
* otherwise we'd never mark anything as obsolete.
|
||||
*/
|
||||
WT_TIME_AGGREGATE_INIT_MERGE(&newest_ta);
|
||||
|
||||
mod = ref->page->modify;
|
||||
if (mod != NULL && mod->rec_result == WT_PM_REC_MULTIBLOCK) {
|
||||
/* Calculate the max stop time point by traversing all multi addresses. */
|
||||
for (multi = mod->mod_multi, i = 0; i < mod->mod_multi_entries; ++multi, ++i)
|
||||
WT_TIME_AGGREGATE_MERGE(session, &newest_ta, &multi->addr.ta);
|
||||
} else if (mod != NULL && mod->rec_result == WT_PM_REC_REPLACE)
|
||||
WT_TIME_AGGREGATE_COPY(&newest_ta, &mod->mod_replace.ta);
|
||||
else if (__wt_ref_addr_copy(session, ref, &addr))
|
||||
WT_TIME_AGGREGATE_COPY(&newest_ta, &addr.ta);
|
||||
|
||||
/* Pages that are totally removed are eliminated during the checkpoint cleanup procedure. */
|
||||
if (WT_TIME_AGGREGATE_HAS_STOP(&newest_ta))
|
||||
return (0);
|
||||
|
||||
/* If there is no transaction or timestamp information available, there is nothing to do. */
|
||||
max_durable_ts = WT_MAX(newest_ta.newest_start_durable_ts, newest_ta.newest_stop_durable_ts);
|
||||
if (newest_ta.newest_txn == WT_TXN_NONE && max_durable_ts == WT_TS_NONE)
|
||||
return (0);
|
||||
|
||||
/* Ensure the time window information has content that is globally visible. */
|
||||
if (!__wt_txn_visible_all(session, newest_ta.newest_txn, max_durable_ts))
|
||||
return (0);
|
||||
|
||||
/* Mark the page dirty to remove any obsolete information during reconciliation. */
|
||||
__wt_verbose(session, WT_VERB_EVICT,
|
||||
"%p in-memory page obsolete time window: time aggregate %s", (void *)ref,
|
||||
__wt_time_aggregate_to_string(&newest_ta, time_string));
|
||||
|
||||
WT_RET(__wt_page_modify_init(session, ref->page));
|
||||
__wt_page_modify_set(session, ref->page);
|
||||
|
||||
/*
|
||||
* Save that another tree has been processed if that's the first time it gets cleaned and update
|
||||
* the number of pages made dirty for that tree.
|
||||
*/
|
||||
if (btree->obsolete_tw_pages == 0)
|
||||
conn->heuristic_controls.obsolete_tw_btree_count++;
|
||||
btree->obsolete_tw_pages++;
|
||||
WT_STAT_CONN_DATA_INCR(session, cache_eviction_dirty_obsolete_tw);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __evict_review --
|
||||
* Get exclusive access to the page and review the page and its subtree for conditions that
|
||||
@@ -712,9 +599,6 @@ __evict_review(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t evict_flags, bool
|
||||
if (F_ISSET(session->dhandle, WT_DHANDLE_DEAD))
|
||||
return (0);
|
||||
|
||||
/* Review the obsolete time window information before eviction. */
|
||||
WT_RET(__evict_review_obsolete_time_window(session, ref));
|
||||
|
||||
/*
|
||||
* Retrieve the modified state of the page. This must happen after the check for evictable
|
||||
* internal pages otherwise there is a race where a page could be marked modified due to a child
|
||||
|
||||
@@ -227,12 +227,6 @@ struct __wt_btree {
|
||||
#define WT_BTREE_CLEAN_MINUTES 10
|
||||
uint64_t clean_ckpt_timer;
|
||||
|
||||
/*
|
||||
* Track the number of obsolete time window pages that are changed into dirty page
|
||||
* reconciliation by the eviction.
|
||||
*/
|
||||
uint32_t obsolete_tw_pages;
|
||||
|
||||
/*
|
||||
* We flush pages from the tree (in order to make checkpoint faster), without a high-level lock.
|
||||
* To avoid multiple threads flushing at the same time, lock the tree.
|
||||
|
||||
@@ -63,26 +63,6 @@ struct __wt_bucket_storage {
|
||||
(s)->bucket_storage = __saved_bstorage; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* WT_HEURISTIC_CONTROLS --
|
||||
* Heuristic controls configuration.
|
||||
*/
|
||||
struct __wt_heuristic_controls {
|
||||
/*
|
||||
* The controls below deal with the cleanup of obsolete time window information. This process
|
||||
* can be configured on two levels:
|
||||
* - The maximum number of btrees to process in a single checkpoint,
|
||||
* - The maximum number of pages per btree to process in a single checkpoint.
|
||||
*/
|
||||
|
||||
/* Number of btrees processed in the current checkpoint. */
|
||||
uint32_t obsolete_tw_btree_count;
|
||||
/* Maximum number of btrees that can be processed per checkpoint. */
|
||||
uint32_t obsolete_tw_btree_max;
|
||||
/* Maximum number of pages that can be processed per btree. */
|
||||
uint32_t obsolete_tw_pages_dirty_max;
|
||||
};
|
||||
|
||||
/*
|
||||
* WT_KEYED_ENCRYPTOR --
|
||||
* A list entry for an encryptor with a unique (name, keyid).
|
||||
@@ -286,8 +266,6 @@ struct __wt_connection_impl {
|
||||
/* Configuration */
|
||||
const WT_CONFIG_ENTRY **config_entries;
|
||||
|
||||
WT_HEURISTIC_CONTROLS heuristic_controls; /* Heuristic controls configuration */
|
||||
|
||||
uint64_t operation_timeout_us; /* Maximum operation period before rollback */
|
||||
|
||||
const char *optrack_path; /* Directory for operation logs */
|
||||
|
||||
@@ -771,8 +771,6 @@ extern int __wt_hazard_set_func(WT_SESSION_IMPL *session, WT_REF *ref, bool *bus
|
||||
const char *func, int line
|
||||
#endif
|
||||
) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_heuristic_controls_config(WT_SESSION_IMPL *session, const char *cfg[])
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_hex2byte(const u_char *from, u_char *to)
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to)
|
||||
|
||||
@@ -445,7 +445,6 @@ struct __wt_connection_stats {
|
||||
int64_t cache_eviction_deepen;
|
||||
int64_t cache_write_hs;
|
||||
int64_t cache_pages_inuse;
|
||||
int64_t cache_eviction_dirty_obsolete_tw;
|
||||
int64_t cache_eviction_app;
|
||||
int64_t cache_eviction_pages_in_parallel_with_checkpoint;
|
||||
int64_t cache_eviction_pages_queued;
|
||||
@@ -919,7 +918,6 @@ struct __wt_dsrc_stats {
|
||||
int64_t cache_read_overflow;
|
||||
int64_t cache_eviction_deepen;
|
||||
int64_t cache_write_hs;
|
||||
int64_t cache_eviction_dirty_obsolete_tw;
|
||||
int64_t cache_read;
|
||||
int64_t cache_read_deleted;
|
||||
int64_t cache_read_deleted_prepared;
|
||||
|
||||
@@ -162,7 +162,3 @@
|
||||
if ((source)->prepare != 0) \
|
||||
(dest)->prepare = 1; \
|
||||
} while (0)
|
||||
|
||||
/* Check if the stop time aggregate is set. */
|
||||
#define WT_TIME_AGGREGATE_HAS_STOP(ta) \
|
||||
((ta)->newest_stop_txn != WT_TXN_MAX || (ta)->newest_stop_ts != WT_TS_MAX)
|
||||
|
||||
1028
src/third_party/wiredtiger/src/include/wiredtiger.in
vendored
1028
src/third_party/wiredtiger/src/include/wiredtiger.in
vendored
File diff suppressed because it is too large
Load Diff
@@ -199,8 +199,6 @@ struct __wt_fstream;
|
||||
typedef struct __wt_fstream WT_FSTREAM;
|
||||
struct __wt_hazard;
|
||||
typedef struct __wt_hazard WT_HAZARD;
|
||||
struct __wt_heuristic_controls;
|
||||
typedef struct __wt_heuristic_controls WT_HEURISTIC_CONTROLS;
|
||||
struct __wt_ikey;
|
||||
typedef struct __wt_ikey WT_IKEY;
|
||||
struct __wt_index;
|
||||
|
||||
@@ -105,7 +105,6 @@ static const char *const __stats_dsrc_desc[] = {
|
||||
"cache: overflow pages read into cache",
|
||||
"cache: page split during eviction deepened the tree",
|
||||
"cache: page written requiring history store records",
|
||||
"cache: pages dirtied due to obsolete time window",
|
||||
"cache: pages read into cache",
|
||||
"cache: pages read into cache after truncate",
|
||||
"cache: pages read into cache after truncate in prepare state",
|
||||
@@ -374,7 +373,6 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats)
|
||||
stats->cache_read_overflow = 0;
|
||||
stats->cache_eviction_deepen = 0;
|
||||
stats->cache_write_hs = 0;
|
||||
stats->cache_eviction_dirty_obsolete_tw = 0;
|
||||
stats->cache_read = 0;
|
||||
stats->cache_read_deleted = 0;
|
||||
stats->cache_read_deleted_prepared = 0;
|
||||
@@ -630,7 +628,6 @@ __wt_stat_dsrc_aggregate_single(WT_DSRC_STATS *from, WT_DSRC_STATS *to)
|
||||
to->cache_read_overflow += from->cache_read_overflow;
|
||||
to->cache_eviction_deepen += from->cache_eviction_deepen;
|
||||
to->cache_write_hs += from->cache_write_hs;
|
||||
to->cache_eviction_dirty_obsolete_tw += from->cache_eviction_dirty_obsolete_tw;
|
||||
to->cache_read += from->cache_read;
|
||||
to->cache_read_deleted += from->cache_read_deleted;
|
||||
to->cache_read_deleted_prepared += from->cache_read_deleted_prepared;
|
||||
@@ -888,7 +885,6 @@ __wt_stat_dsrc_aggregate(WT_DSRC_STATS **from, WT_DSRC_STATS *to)
|
||||
to->cache_read_overflow += WT_STAT_READ(from, cache_read_overflow);
|
||||
to->cache_eviction_deepen += WT_STAT_READ(from, cache_eviction_deepen);
|
||||
to->cache_write_hs += WT_STAT_READ(from, cache_write_hs);
|
||||
to->cache_eviction_dirty_obsolete_tw += WT_STAT_READ(from, cache_eviction_dirty_obsolete_tw);
|
||||
to->cache_read += WT_STAT_READ(from, cache_read);
|
||||
to->cache_read_deleted += WT_STAT_READ(from, cache_read_deleted);
|
||||
to->cache_read_deleted_prepared += WT_STAT_READ(from, cache_read_deleted_prepared);
|
||||
@@ -1174,7 +1170,6 @@ static const char *const __stats_connection_desc[] = {
|
||||
"cache: page split during eviction deepened the tree",
|
||||
"cache: page written requiring history store records",
|
||||
"cache: pages currently held in the cache",
|
||||
"cache: pages dirtied due to obsolete time window",
|
||||
"cache: pages evicted by application threads",
|
||||
"cache: pages evicted in parallel with checkpoint",
|
||||
"cache: pages queued for eviction",
|
||||
@@ -1725,7 +1720,6 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
|
||||
stats->cache_eviction_deepen = 0;
|
||||
stats->cache_write_hs = 0;
|
||||
/* not clearing cache_pages_inuse */
|
||||
stats->cache_eviction_dirty_obsolete_tw = 0;
|
||||
stats->cache_eviction_app = 0;
|
||||
stats->cache_eviction_pages_in_parallel_with_checkpoint = 0;
|
||||
stats->cache_eviction_pages_queued = 0;
|
||||
@@ -2266,7 +2260,6 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *
|
||||
to->cache_eviction_deepen += WT_STAT_READ(from, cache_eviction_deepen);
|
||||
to->cache_write_hs += WT_STAT_READ(from, cache_write_hs);
|
||||
to->cache_pages_inuse += WT_STAT_READ(from, cache_pages_inuse);
|
||||
to->cache_eviction_dirty_obsolete_tw += WT_STAT_READ(from, cache_eviction_dirty_obsolete_tw);
|
||||
to->cache_eviction_app += WT_STAT_READ(from, cache_eviction_app);
|
||||
to->cache_eviction_pages_in_parallel_with_checkpoint +=
|
||||
WT_STAT_READ(from, cache_eviction_pages_in_parallel_with_checkpoint);
|
||||
|
||||
@@ -833,7 +833,6 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[])
|
||||
cache->evict_max_page_size = 0;
|
||||
cache->evict_max_ms = 0;
|
||||
cache->reentry_hs_eviction_ms = 0;
|
||||
conn->heuristic_controls.obsolete_tw_btree_count = 0;
|
||||
conn->rec_maximum_hs_wrapup_milliseconds = 0;
|
||||
conn->rec_maximum_image_build_milliseconds = 0;
|
||||
conn->rec_maximum_milliseconds = 0;
|
||||
|
||||
21
src/third_party/wiredtiger/test/evergreen.yml
vendored
21
src/third_party/wiredtiger/test/evergreen.yml
vendored
@@ -173,7 +173,6 @@ functions:
|
||||
# Autoconf/Libtool if $is_cmake_build is not declared.
|
||||
if [ ${is_cmake_build|false} = true ]; then
|
||||
if [ "$OS" = "Windows_NT" ]; then
|
||||
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
|
||||
# Use the Windows powershell script to configure the CMake build.
|
||||
# We execute it in a powershell environment as its easier to detect and source the Visual Studio
|
||||
# toolchain in a native Windows environment. We can't easily execute the build in a cygwin environment.
|
||||
@@ -240,9 +239,7 @@ functions:
|
||||
${make_command|ninja} ${smp_command|} 2>&1
|
||||
fi
|
||||
elif [ "Windows_NT" == "$OS" ]; then
|
||||
# Add paths to both global and user Python scripts
|
||||
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
|
||||
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
|
||||
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
|
||||
|
||||
python --version
|
||||
python -m pip install scons==3.1.1
|
||||
@@ -436,7 +433,7 @@ functions:
|
||||
set -o verbose
|
||||
|
||||
if [ "Windows_NT" = "$OS" ]; then
|
||||
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
|
||||
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
|
||||
export "PYTHONPATH=$(pwd)/../lang/python/wiredtiger):$(cygpath -w $(pwd)/../lang/python)"
|
||||
fi
|
||||
if [ ${is_cmake_build|false} = true ]; then
|
||||
@@ -1989,10 +1986,7 @@ tasks:
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
|
||||
# Add paths to both global and user Python scripts
|
||||
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
|
||||
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
|
||||
|
||||
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
|
||||
python --version
|
||||
python -m pip install scons==3.1.1
|
||||
scons-3.1.1.bat ${scons_smp_command|} "CFLAGS=/Gv /wd4090 /wd4996 /we4047 /we4024 /TC /we4100 /we4133" wiredtiger.dll libwiredtiger.lib
|
||||
@@ -2010,10 +2004,7 @@ tasks:
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
|
||||
# Add paths to both global and user Python scripts
|
||||
export "PATH=/cygdrive/c/python/Python311:/cygdrive/c/python/Python311/Scripts:$PATH"
|
||||
export "PATH=/cygdrive/c/Users/$USER/AppData/Roaming/Python/Python311/Scripts:$PATH"
|
||||
|
||||
export "PATH=/cygdrive/c/Python311:/cygdrive/c/Python311/Scripts:$PATH"
|
||||
python --version
|
||||
python -m pip install scons==3.1.1
|
||||
# The check target is not run in parallel.
|
||||
@@ -3615,7 +3606,7 @@ buildvariants:
|
||||
run_on:
|
||||
- windows-64-vs2017-test
|
||||
expansions:
|
||||
python_binary: '/cygdrive/c/python/Python311/python'
|
||||
python_binary: 'python'
|
||||
scons_smp_command: -j $(echo "$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) * 2" | bc)
|
||||
tasks:
|
||||
- name: compile
|
||||
@@ -3628,7 +3619,7 @@ buildvariants:
|
||||
run_on:
|
||||
- windows-64-vs2017-test
|
||||
expansions:
|
||||
python_binary: '/cygdrive/c/python/Python311/python'
|
||||
python_binary: 'python'
|
||||
is_cmake_build: true
|
||||
test_env_vars: WT_BUILDDIR=$(git rev-parse --show-toplevel)/cmake_build
|
||||
windows_configure_flags: -vcvars_bat "'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat'"
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Public Domain 2014-present MongoDB, Inc.
|
||||
# Public Domain 2008-2014 WiredTiger, Inc.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import wttest
|
||||
|
||||
# eviction_util.py
|
||||
# Shared base class used by eviction tests.
|
||||
class eviction_util(wttest.WiredTigerTestCase):
|
||||
|
||||
def get_stat(self, stat, uri = ""):
|
||||
stat_cursor = self.session.open_cursor(f'statistics:{uri}')
|
||||
val = stat_cursor[stat][2]
|
||||
stat_cursor.close()
|
||||
return val
|
||||
|
||||
def populate(self, uri, start_key, num_keys, value):
|
||||
c = self.session.open_cursor(uri, None)
|
||||
for k in range(start_key, num_keys):
|
||||
self.session.begin_transaction()
|
||||
c[k] = value
|
||||
self.session.commit_transaction("commit_timestamp=" + self.timestamp_str(k + 1))
|
||||
c.close()
|
||||
@@ -1,98 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Public Domain 2014-present MongoDB, Inc.
|
||||
# Public Domain 2008-2014 WiredTiger, Inc.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from eviction_util import eviction_util
|
||||
from wiredtiger import stat
|
||||
from wtscenario import make_scenarios
|
||||
|
||||
# test_eviction02.py
|
||||
# Verify evicting a clean page removes any obsolete time window information present on the page.
|
||||
class test_eviction02(eviction_util):
|
||||
conn_config_common = 'cache_size=10MB,statistics=(all),statistics_log=(json,wait=1,on_close=true)'
|
||||
|
||||
# These settings set a limit to the number of btrees/pages that can be cleaned up per btree per
|
||||
# checkpoint.
|
||||
conn_config_values = [
|
||||
('no_btrees', dict(expected_cleanup=False, obsolete_tw_max=0, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_btree_max=0]')),
|
||||
('no_pages', dict(expected_cleanup=False, obsolete_tw_max=0, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=0]')),
|
||||
('50_pages', dict(expected_cleanup=True, obsolete_tw_max=50, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=50]')),
|
||||
('100_pages', dict(expected_cleanup=True, obsolete_tw_max=100, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=100]')),
|
||||
('500_pages', dict(expected_cleanup=True, obsolete_tw_max=500, conn_config=f'{conn_config_common},heuristic_controls=[obsolete_tw_pages_dirty_max=500]')),
|
||||
]
|
||||
|
||||
scenarios = make_scenarios(conn_config_values)
|
||||
|
||||
def test_evict(self):
|
||||
create_params = 'key_format=i,value_format=S'
|
||||
nrows = 10000
|
||||
prev_obsolete_tw_value = 0
|
||||
# Stats may have a stale value, allow some buffer.
|
||||
threshold = self.obsolete_tw_max * 2
|
||||
uri = 'table:eviction02'
|
||||
value = 'k' * 1024
|
||||
|
||||
self.session.create(uri, create_params)
|
||||
|
||||
for i in range(10):
|
||||
# Add some data.
|
||||
start_key = nrows * i
|
||||
num_keys = nrows * (i + 1)
|
||||
self.populate(uri, start_key, num_keys, value)
|
||||
|
||||
# Make all the inserted data stable and checkpoint to make everything clean.
|
||||
self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(num_keys))
|
||||
self.session.checkpoint()
|
||||
|
||||
# Bump the oldest timestamp to make some of the previously inserted data globally
|
||||
# visible. This makes any time window informaton associated with that data obsolete and
|
||||
# eligible for cleanup.
|
||||
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(num_keys // 2))
|
||||
|
||||
# Retrieve the number of pages we have cleaned up so far.
|
||||
current_obsolete_tw_value = self.get_stat(stat.dsrc.cache_eviction_dirty_obsolete_tw, uri)
|
||||
if self.expected_cleanup:
|
||||
# The difference between two iterations should not exceed the maximum number of
|
||||
# pages configured as each iteration contains one checkpoint that resets the limit.
|
||||
# Note that we cannot assert after each iteration that we have cleaned pages as it
|
||||
# depends on eviction that may not always work.
|
||||
diff = current_obsolete_tw_value - prev_obsolete_tw_value
|
||||
prev_obsolete_tw_value = current_obsolete_tw_value
|
||||
assert diff <= threshold, f"Unexpected number of pages with obsolete tw cleaned: {diff} (max {threshold})"
|
||||
else:
|
||||
self.assertEqual(current_obsolete_tw_value, 0)
|
||||
|
||||
# Verify the btree and connection-level stat. If we expect some cleanup, by the end of the
|
||||
# test, we must have done some work.
|
||||
btree_stat = self.get_stat(stat.dsrc.cache_eviction_dirty_obsolete_tw, uri)
|
||||
conn_stat = self.get_stat(stat.conn.cache_eviction_dirty_obsolete_tw)
|
||||
if self.expected_cleanup:
|
||||
self.assertGreater(btree_stat, 0)
|
||||
self.assertGreater(conn_stat, 0)
|
||||
else:
|
||||
self.assertEqual(btree_stat, 0)
|
||||
self.assertEqual(conn_stat, 0)
|
||||
Reference in New Issue
Block a user