Warning: log write time 600ms, size 43KB

突然才发现一个数据库的LGWR进程的跟踪文件scm2_lgwr_5690.trc有大量的告警信息,如下所示:

Warning: ;log write time 680ms, size 11569KB
*** ;2015-01-04 02:41:17.122
Warning: ;log write time 520ms, size 2764KB
*** ;2015-01-04 03:11:40.885
Warning: ;log write time 880ms, size 1KB
*** ;2015-01-04 03:24:04.357
Warning: ;log write time 500ms, size 1KB
*** ;2015-01-04 03:29:11.160
Warning: ;log write time 510ms, size 2KB
*** ;2015-01-04 03:30:22.383
Warning: ;log write time 540ms, size 2KB
*** ;2015-01-04 04:04:09.133
Warning: ;log write time 680ms, size 3KB
*** ;2015-01-04 04:15:53.617
Warning: ;log write time 620ms, size 25KB
*** ;2015-01-04 04:20:06.502
Warning: ;log write time 940ms, size 5KB
*** ;2015-01-04 04:31:11.049
Warning: ;log write time 520ms, size 43KB
*** ;2015-01-04 04:32:52.570
Warning: ;log write time 520ms, size 33KB
*** ;2015-01-04 04:33:22.023
Warning: ;log write time 1600ms, size 257KB
*** ;2015-01-04 04:33:22.609
Warning: log write time 590ms, size 443KB

 

搜索了Metalink上关于该告警的阐述Metalink ID 601316.1,具体内容如下所示(英文部分):

CHANGES

The problem surfaced after upgrading to 10.2.0.4.

CAUSE

The above warning messages has been introduced in 10.2.0.4 patchset.

The warning message will be generated only if the log write time is more than 500 ms and it will be written to the lgwr trace file.

SOLUTION

These messages are expected in a 10.2.0.4 database in case the log write is more than 500 ms.

This is a warning which means that the write process is not as fast as it intented to be.

So, probably you need to check if the disk is slow or not or for any potential OS causes.

If everything looks fine at the hardware level or OS level i.e if enviroment is unable to deliver a faster service because of its own nature,then you can ignore this message.then you can safely ignore these messages. The trace file can easily be deleted or truncated.

Also, according to Bug:7559549 , these trace can be disabled by setting event 10468 level 4.

 

刚好我们数据库版本也是10.2.0.4.0,于是我检查了另外其它几台数据库,发现基本上都有这类错误,根据官方文档,如果磁盘没有什么问题,可以忽略这个告警信息。另外我也在两位大师Eygle&惜分飞博客里面发现了对这个告警现象的记录、描述.应该可以忽略这个告警。另外,也可以通过下面命令取消该trace命令,如下所示:

ALTER SYSTEM SET EVENTS '10468 trace name context off';

 

参考资料:

http://www.eygle.com/archives/2009/11/log_write_time.html

http://www.xifenfei.com/1563.html

 

#include "Fuction.h" #define TAEM_NUMBER 2025555625 #define TAEM_ADDRESS 0x000000 //共四字节,存储位置 000000 - 000003 #define SFLASH_ID 0xC84013 #include "Fuction.h" #define TAEM_NUMBER 2025555625 #define TAEM_ADDRESS 0x000000 //共四字节,存储位置 000000 - 000003 #define SFLASH_ID 0xC84013 extern uint8_t TASK; extern uint8_t rtc_year, rtc_month, rtc_day, rtc_hour, rtc_min, rtc_sec; extern int sdk_begin_flag; uint32_t GD_flash_id = 0; uint32_t read_team_number = 0; uint8_t show[] = "system idle"; uint32_t sys_ticks = 0; volatile uint32_t last_sample_time = 0; TestStruct test_struct; ConfigStruct config_struct; // 定义 gCurrentRatio float gCurrentRatio = 1.0f; // 定义 ratioTaskState uint8_t ratioTaskState = 0; // 定义 ratioOutputBuffer uint8_t ratioOutputBuffer[100] = {0}; // 采样控制变量 volatile uint8_t sampling = 0; volatile uint8_t led_state = 0; uint32_t sample_period = 5000; // 默认采样周期为 5 秒 #include <stdio.h> #include "adc.h" // 包含真实的 ADC 驱动头文件 // 定义 limitTaskState uint8_t limitTaskState = 0; // 定义 limitOutputBuffer uint8_t limitOutputBuffer[100] = {0}; /** * 从Flash读取变比 */ float readRatioFromFlash(void) { uint32_t rawData = 0; spi_flash_buffer_read((uint8_t*)&rawData, 0x00010000, sizeof(uint32_t)); float ratio; memcpy(&ratio, &rawData, sizeof(float)); return ratio; } /** * 保存变比到Flash */ int saveRatioToFlash(float ratio) { spi_flash_write_enable(); spi_flash_sector_erase(0x00010000); uint32_t rawData; memcpy(&rawData, &ratio, sizeof(float)); spi_flash_buffer_write((uint8_t*)&rawData, 0x00010000, sizeof(uint32_t)); spi_flash_wait_for_write_end(); return 0; } /** * 初始化变比参数(系统启动时调用) */ void initRatioParameter(void) { gCurrentRatio = readRatioFromFlash(); // 从Flash读取变比 if (gCurrentRatio < 0.0f || gCurrentRatio > 100.0f) { gCurrentRatio = 1.0f; // 无效值设为默认 saveRatioToFlash(gCurrentRatio); } } #define RATIO_ADDRESS 0x00010000 // 扇区100 (256KB边界) #define LIMIT_ADDRESS 0x00020000 // 扇区200 (512KB边界) #define PERIOD_ADDRESS 0x00030000 // 扇区300 (768KB边界) // 通用Flash读取函数 float readFromFlash(uint32_t addr, float default_val, float min_val, float max_val) { uint32_t rawData = 0; if(spi_flash_buffer_read((uint8_t*)&rawData, addr, sizeof(uint32_t)) != SUCCESS) { return default_val; } float value; memcpy(&value, &rawData, sizeof(float)); if(value < min_val || value > max_val) { saveToFlash(addr, default_val); // 保存默认值 return default_val; } return value; } // 优化任务状态机 - 使用静态变量保持状态 void processRatioTask(void) { static uint8_t state = 0; switch(state) { case 0: // 初始化状态 sprintf((char*)ratioOutputBuffer, "Ratio=%.1f\r\nInput(0-100):", gCurrentRatio); transmit_data(ratioOutputBuffer, strlen((char*)ratioOutputBuffer)); state = 1; clear_rx_buffer(); // 清空接收缓冲区 break; case 1: // 等待输入 if (has_valid_input()) { float newRatio = parse_float_input(); if (newRatio >= 0.0f && newRatio <= 100.0f) { if (saveRatioToFlash(newRatio) == 0) { gCurrentRatio = newRatio; sprintf((char*)ratioOutputBuffer, "Success! New ratio: %.1f", newRatio); } else { sprintf((char*)ratioOutputBuffer, "Flash write error!"); } } else { sprintf((char*)ratioOutputBuffer, "Invalid range (0-100)!"); } transmit_data(ratioOutputBuffer, strlen((char*)ratioOutputBuffer)); state = 0; // 重置状态机 TASK = 0; // 清除任务标志 } break; } } // 新增采样周期设置功能 void set_sample_period(uint32_t period_ms) { if (period_ms < 100) period_ms = 100; // 最小100ms if (period_ms > 60000) period_ms = 60000; // 最大60秒 // 保存到Flash spi_flash_write_enable(); spi_flash_sector_erase(PERIOD_ADDRESS); spi_flash_buffer_write((uint8_t*)&period_ms, PERIOD_ADDRESS, sizeof(uint32_t)); spi_flash_wait_for_write_end(); // 更新当前值 sample_period = period_ms; printf("New sample period: %lums\r\n", sample_period); } /** * 在 OLED 上显示电压值 */ void oled_show_voltage(float voltage) { char voltage_str[20]; sprintf(voltage_str, "%.2f V", voltage); oled_show_string(2, 1, (u8*)voltage_str, 16); oled_refresh(); } void log_sample(float voltage) { static uint32_t count = 0; if(count % 100 == 0) { // 每100次采样保存一次 char log_entry[50]; sprintf(log_entry, "%lu,%.2f\n", get_timestamp(), voltage); write_to_sd_card(log_entry); } count++; } /** * 真实的 ADC 采样函数 */ float adc_sample(void) { // 使用真实的 ADC 采样代码 uint16_t adcValue = adc_get_result(ADC_CHANNEL_0); // 假设使用通道 0 float voltage = (adcValue * 3.3f) / 4096.0f; // 假设 ADC 参考电压为 3.3V return voltage * gCurrentRatio; // 应用变比 } /** * 定时器回调函数,用于控制采样周期 */ void systick_callback(void) { sys_ticks++; // 确保 sys_ticks 正在递增 if (sampling) { if (sys_ticks - last_sample_time >= sample_period / 1000) { // 将毫秒转换为滴答 last_sample_time = sys_ticks; // 触发采样 float voltage = adc_sample(); printf("ADC Voltage: %.2f V\r\n", voltage); // 更新 OLED 显示 oled_show_voltage(voltage); // 检查是否超过阈值 if (voltage > config_struct.limit) { led_alarm_on(); // 点亮报警 LED printf("Voltage OverLimit! Limit: %.2f V\r\n", config_struct.limit); } else { led_alarm_off(); // 关闭报警 LED } // 切换 LED 状态(每秒闪烁一次) led_state = !led_state; if (led_state) { led_on(); // 假设 LED1 用于指示采样状态 } else { led_off(); } } } } /** * 开启 ADC 采样 */ void start_sample(void) { if (!sampling) { sampling = 1; last_sample_time = sys_ticks; // 重置采样计时器 printf("Sampling started\r\n"); // 更新 OLED 显示 oled_clear(); oled_show_string(0, 0, "sampling", 8); oled_refresh(); // LED1 按 1s 周期闪烁 led_state = 1; } } /** * 停止 ADC 采样 */ void stop_sample(void) { if (sampling) { sampling = 0; printf("Sampling stopped\r\n"); oled_show_string(1, 1, (u8*)"system idle", 16); oled_refresh(); led_off(); // 关闭指示 LED } } void sys_config(void) { // 时钟初始化 systick_config(); // 串口初始化 usart_dma_init(); /*--系统上电初始化测试--*/ printf("\n"); printf("====system init====\r\n"); delay_1ms(10); // RTC初始化 RTC_Init(); // OLED初始化 oled_init(); // Flash初始化 spi_flash_init(); // FATFS初始化 bsp_tfcard_init(); initRatioParameter(); write_uint32_to_flash(TAEM_NUMBER, TAEM_ADDRESS); delay_1ms(10); read_team_number = 0; read_team_number = read_uint32_from_flash(TAEM_ADDRESS); printf("Device_ID:2025-CIMC-%d \r\n", read_team_number); printf("====system ready====\r\n"); oled_show_string(1, 1, (u8*)"system idle", 16); oled_refresh(); // 初始化参数(带默认值) gCurrentRatio = readFromFlash(RATIO_ADDRESS, 1.0f, 0.0f, 100.0f); config_struct.limit = readFromFlash(LIMIT_ADDRESS, 30.0f, 0.0f, 500.0f); sample_period = readFromFlash(PERIOD_ADDRESS, 5000, 100, 60000); // 初始化ADC adc_init(); } /** * 从Flash读取阈值 */ float readLimitFromFlash(void) { uint32_t rawData = 0; spi_flash_buffer_read((uint8_t*)&rawData, 0x00020000, sizeof(uint32_t)); float limit; memcpy(&limit, &rawData, sizeof(float)); return limit; } /** * 保存阈值到Flash */ int saveLimitToFlash(float limit) { spi_flash_write_enable(); spi_flash_sector_erase(0x00020000); uint32_t rawData; memcpy(&rawData, &limit, sizeof(float)); spi_flash_buffer_write((uint8_t*)&rawData, 0x00020000, sizeof(uint32_t)); spi_flash_wait_for_write_end(); return 0; } /** * 处理阈值设置任务(在主循环中调用) */ void processLimitTask(void) { switch (limitTaskState) { case 0: // 状态0:输出提示并等待输入 sprintf((char*)limitOutputBuffer, "Limit=%.1f\r\nInput value(0-500):\r\n", config_struct.limit); transmit_data(limitOutputBuffer, strlen((char*)limitOutputBuffer)); limitTaskState = 1; // 切换到输入等待状态 // 清空输入缓冲区 memset(rxbuffer, 0, MAX_BUFFER_SIZE); g_rx_length = 0; break; case 1: // 状态1:检测是否有新输入 if (g_transfer_complete == SET && g_rx_length > 0) { g_transfer_complete = RESET; float newLimit; // 解析输入(添加超时保护) if (sscanf((char*)rxbuffer, "%f", &newLimit) == 1) { // 验证输入有效性 if (newLimit >= 0.0f && newLimit <= 500.0f) { // 有效输入 config_struct.limit = newLimit; if (saveLimitToFlash(newLimit) == 0) { sprintf((char*)limitOutputBuffer, "limit modified success\r\nLimit = %.1f\r\n", newLimit); } else { sprintf((char*)limitOutputBuffer, "flash write error\r\nLimit=%.1f\r\n", config_struct.limit); } } else { // 无效输入(范围错误) sprintf((char*)limitOutputBuffer, "limit invalid (0-500 expected)\r\nLimit=%.1f\r\n", config_struct.limit); } } else { // 无效输入(非数字) sprintf((char*)limitOutputBuffer, "limit invalid (numeric value expected)\r\nLimit=%.1f\r\n", config_struct.limit); } // 输出结果并重置状态 transmit_data(limitOutputBuffer, strlen((char*)limitOutputBuffer)); limitTaskState = 2; // 切换到完成状态 } break; case 2: // 状态2:等待任务标志清除 if (TASK != 9) { limitTaskState = 0; // 重置状态 } break; default: limitTaskState = 0; break; } } /** * 初始化阈值参数(系统启动时调用) */ void initLimitParameter(void) { config_struct.limit = readLimitFromFlash(); // 从Flash读取阈值 if (config_struct.limit < 0.0f || config_struct.limit > 500.0f) { config_struct.limit = 30.0f; // 无效值设为默认 saveLimitToFlash(config_struct.limit); } } void sys_sdk(void) { switch (TASK) { case 1: if (sdk_begin_flag == 1) { // 设置RTC时间 rtc_setup(rtc_year, rtc_month, rtc_day, rtc_hour, rtc_min, rtc_sec); sdk_begin_flag = 0; } break; case 3: if (sdk_begin_flag == 1) { // Flash自检 GD_flash_id = spi_flash_read_id(); if (GD_flash_id == SFLASH_ID) { printf("flash.........ok\r\n"); test_struct.flash_status = 1; } else { printf("flash.........fail\r\n"); test_struct.flash_status = 0; } // TF自检 if (bsp_tfcard_init() == TF_OK) { printf("TF card.........ok\r\n"); test_struct.tf_card_status = 1; } else { printf("TF card.........fail\r\n"); test_struct.tf_card_status = 0; } // 输出 if (test_struct.flash_status == 1) { printf("flash ID: 0x%02X\r\n", GD_flash_id); } else { printf("can not find flash\r\n"); } if (test_struct.tf_card_status == 1) { test_struct.tf_memory = sd_card_capacity_get(); printf("TF card memory %" PRIu32 "KB\r\n", test_struct.tf_memory); } else { printf("can not find TFcard\r\n"); } rtc_show_time(); printf("====system selftest====\r\n"); sdk_begin_flag = 0; } break; case 4:// ratio { processRatioTask(); } break; case 5:// start { start_sample(); } break; case 6:// stop { stop_sample(); } break; case 7:// config save { // 保存配置逻辑可以在这里实现 printf("Config saved\r\n"); } break; case 8:// config read { // 读取配置逻辑可以在这里实现 printf("Config read\r\n"); } break; case 9:// limit { processLimitTask(); } break; default: break; } } void sys_usr(void) { while (1) { sys_sdk(); } }出现了Build started: Project: Project *** Using Compiler &#39;V5.06 update 6 (build 750)&#39;, folder: &#39;C:\Keil_v5\ARM\ARMCC\Bin&#39; Build target &#39;CIMC_GD32_fatfs_driver&#39; compiling Fuction.c... ..\sysFunction\Fuction.c(87): error: #41: expression must have arithmetic or pointer type if(spi_flash_buffer_read((uint8_t*)&rawData, addr, sizeof(uint32_t)) != SUCCESS) { ..\sysFunction\Fuction.c(95): warning: #223-D: function "saveToFlash" declared implicitly saveToFlash(addr, default_val); // 保存默认值 ..\sysFunction\Fuction.c(109): warning: #223-D: function "clear_rx_buffer" declared implicitly clear_rx_buffer(); // 清空接收缓冲区 ..\sysFunction\Fuction.c(113): warning: #223-D: function "has_valid_input" declared implicitly if (has_valid_input()) { ..\sysFunction\Fuction.c(114): warning: #223-D: function "parse_float_input" declared implicitly float newRatio = parse_float_input(); ..\sysFunction\Fuction.c(164): warning: #223-D: function "get_timestamp" declared implicitly sprintf(log_entry, "%lu,%.2f\n", get_timestamp(), voltage); ..\sysFunction\Fuction.c(165): warning: #223-D: function "write_to_sd_card" declared implicitly write_to_sd_card(log_entry); ..\sysFunction\Fuction.c(198): warning: #223-D: function "led_alarm_on" declared implicitly led_alarm_on(); // 点亮报警 LED ..\sysFunction\Fuction.c(201): warning: #223-D: function "led_alarm_off" declared implicitly led_alarm_off(); // 关闭报警 LED ..\sysFunction\Fuction.c(207): warning: #223-D: function "led_on" declared implicitly led_on(); // 假设 LED1 用于指示采样状态 ..\sysFunction\Fuction.c(209): warning: #223-D: function "led_off" declared implicitly led_off(); ..\sysFunction\Fuction.c(243): warning: #223-D: function "led_off" declared implicitly led_off(); // 关闭指示 LED ..\sysFunction\Fuction.c(478): warning: #1-D: last line of file ends without a newline } ..\sysFunction\Fuction.c: 12 warnings, 1 error ".\Objects\Project.axf" - 1 Error(s), 12 Warning(s). Target not created.cuow
最新发布
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值