Showing posts with label blackboard. Show all posts
Showing posts with label blackboard. Show all posts

Monday, April 20, 2009

SQL Database Point-In-Time Restore of Transaction Log Backup

A Teaching Assistant (TA) deleted all the grades in an assignment in our online learning management system, eLearning (powered by Blackboard Learning System CE). What happened was a series of actions that leaded to this. Here is what was described to me (I'm yet to be able to successfully simulate it):
The TA used the grade book tool to enter the grades of all students in a particular assignment (instead of using the assignment tool). He then changed the due date of that assignment to a later date. The system gave him a warning message, but he simply went ahead to proceed. He subsequently found that all the grades he entered for that assignment were gone.
Now I had to find a way to retrieve the grades from our old backups. But the challenge was he did not remember when (approximate date and time) he entered the grades, and when he modified the assignment properties which caused all the grades to be cleared.

I parsed our web server logs (using Cygwin's gawk) looking for all his POST requests with grade book and other strings in the URL. Yes! I saw the log entires dated April 14 around midnight, with the last update at 0:56am.

Therefore, I restored our elearning database backups (onto a test instance) to the April 14 0:57am state. Here is the SQL script.
restore database webctdatabase from DISK='D:\backupfolder\webctdatabase_backup_200904120005.bak' WITH NORECOVERY, REPLACE

restore database webctdatabase from DISK='D:\backupfolder\webctdatabase_backup_200904140005.dif' WITH NORECOVERY

restore log webctdatabase from DISK='D:\backupfolder\webctdatabase_backup_200904140250.trn' WITH RECOVERY, STOPAT = 'Apr 14, 2009 00:57:00 AM'

restore database webctdatabase$PF from DISK='D:\backupfolder\webctdatabase$PF_backup_200904120005.bak' WITH NORECOVERY, REPLACE

restore database webctdatabase$PF from DISK='D:\backupfolder\webctdatabase$PF_backup_200904140005.dif' WITH NORECOVERY

restore log webctdatabase$PF from DISK='D:\backupfolder\webctdatabase$PF_backup_200904140250.trn' WITH RECOVERY, STOPAT = 'Apr 14, 2009 00:57:00 AM'
A little background info: We ran eLearning full database backup once a week (Sunday), a differential backup nightly (Monday to Saturday), and transaction log backups throughout the day. Therefore, when restoring from backup, I needed to restore the full database backup (as of April 12 Sunday), the last differential backup (as of April 14 Tuesday), and the transaction log backup to the specific point-in-time.

After the restore was completed, I also had to execute the following SQL commands to set the webct and webct$PF users' SID on the test instance properly.
Use webctdatabase
go
sp_change_users_login 'report'

Use webctdatabase
go
sp_change_users_login 'update_one', 'webct', 'webct'

Use webctdatabase
go
sp_change_users_login 'update_one', 'webct$PF', 'webct$PF'


Use webctdatabase$PF
go
sp_change_users_login 'report'

Use webctdatabase$PF
go
sp_change_users_login 'update_one', 'webct', 'webct'

Use webctdatabase$PF
go
sp_change_users_login 'update_one', 'webct$PF', 'webct$PF'
Then I restarted the webct service on the frontend node of the test instance to bring up the application. I logoned to it and could see all the student grades in that section/assignment. We exported them for the TA.

Saved by the transaction log backups.

Tuesday, March 24, 2009

More eLearning User Penetration Numbers

In December 2007, I wrote a script to determine the user penetration rate of eLearning, our online Learning Management System (powered by Blackboard Learning System CE6). We have subsequently upgraded the system to CE8 with all the latest service packs. Fortunately, the script continues to work.

Here are the numbers for the main Pullman campus:

Semester Undergraduate Students Graduate Students Undergraduate + Graduate Students
Total LMS % Total LMS % Total LMS
%
2007 Fall 15441 12862 83.30 1981 749 37.81 17422 13611 78.13
2008 Spring 14383 12079 83.98 1874 747 39.86 16257 12826 78.90
2008 Fall 15571 14521 93.26 1998 1165 58.31 17569 15686 89.28
2009 Spring 14650 12968 88.52 1939 936 48.27 16589 13904 83.81

Wednesday, February 11, 2009

SQL Script to Generate a List of Sections (& Instructors) from Blackboard Learning System CE8

We need to generate a list of all courses/ sections hosted in our Learning Management System (powered by Blackboard Learning System CE8, formerly known as WebCT).

In Blackboard's terminology, all courses and sections are learning contexts. They are hierarchical and their parent-child relationships along with other information are stored in the database. So, the challenge here is to figure out how to write a recursive query.

With a little help from an msdn article: Recursive Queries Using Common Table Expressions, I figured out how to do that today.

The following SQL query will generate a list of all sections ordered by the course names, and the by section names:
with temp1 (parent_learning_context_id, learning_context_id, name, level)
as
(
select parent_learning_context_id, learning_context_id,
name, 0 as level from rpt_learning_context
where parent_learning_context_id IS NULL
union all
select LC.parent_learning_context_id,
LC.learning_context_id, LC.name, level + 1
from rpt_learning_context as LC
inner join temp1 as T
on LC.parent_learning_context_id = T.learning_context_id
)
select T.parent_learning_context_id, LC.name,
T.learning_context_id, T.name from temp1 as T
inner join learning_context as LC
on T.parent_learning_context_id = LC.id
where T.level = 4
order by LC.name, T.name
With a little twist, I can easily modify it to generate a list of all instructors teaching this Spring semester:
with temp1 (parent_learning_context_id, learning_context_id, name, level)
as
(
select parent_learning_context_id, learning_context_id,
name, 0 as level from rpt_learning_context
where parent_learning_context_id IS NULL
union all
select LC.parent_learning_context_id,
LC.learning_context_id, LC.name, level + 1
from rpt_learning_context as LC
inner join temp1 as T
on LC.parent_learning_context_id = T.learning_context_id
)
select LC.name, T.name, P.webct_id_lowercase,
P.name_n_given, P.name_n_family, P.email from temp1 as T
inner join learning_context as LC
on T.parent_learning_context_id = LC.id
inner join rpt_member as M
on M.learning_context_id = T.learning_context_id
inner join person as P
on M.person_id = p.id
where T.level = 4
and LC.name like '%2009_spring%'
and M.role='SINS'
and M.active = '1'
and M.denied_access = '0'
order by T.name
SQL queries - I'm loving it.

Thursday, February 5, 2009

SQL Script to Download Grades from Blackboard Learning System CE8

I just finished a SQL query to download all grade book data from Blackboard Learning System CE8.
select
LC2.name as Semester,
GB.learning_context_name as Section,
P.source_id as StudentID,
GB.user_login_name,
GB.given_name,
GB.family_name,
GB.column_name,
GB.column_type,
GB.original_value,
GB.override,
GB.max_points,
GB.final_value
from rpt_ext_gradebook as GB
inner join rpt_person as P
on P.person_id = GB.person_id
inner join rpt_learning_context as LC1
on GB.learning_context_id = LC1.learning_context_id
inner join rpt_learning_context as LC2
on LC1.parent_learning_context_id = LC2.learning_context_id
where P.demo_user = 0
order by LC2.name, GB.learning_context_name, column_name, user_login_name
This depends on the RPT_EXT_GRADEBOOK background job to run successfully to have the data populated properly.

I ran it against a clone of our production database. It took 1.5 minutes to retrieve 2.2 millions grade records. I spot checked a number of courses (sections). It included the resulting value of grades even when they were calculated by formula. It also gave me the original grades, any overrides made, and the final grades. Very nice!

Tuesday, December 30, 2008

Blackboard CE8 SP2 Upgrade and Scholar Powerlink

We upgraded our Blackboard Learning System CE8 to Service Pack 2 level on production yesterday afternoon. After the upgrade, the Scholar powerlink was no longer working.

The error message was:

An error occured in the communication between your Blackboard system and Scholar.
The Blackboard system clock may be incorrect.
If you continue to see this error, contact your Blackboard system administrator.

Multiple of us tested it, and we consistently received the above error.

This was really upsetting because this was one piece of the upgrade we could not test on our development cluster. We had a lot of troubles when we initially registered our development cluster onto the Blackboard's Scholar system for configuration testing, which then took away the ability of our production system to be registered. It took Blackboard technical support and their Beyond team over three months to resolve this (basically deleted the registration record of our development cluster in their database). As it turns out, Blackboard does not support both development and production clusters to be registered onto their Scholar system. Therefore we cannot test Scholar powerlink when we tested SP2 upgrade on development.

To my surprise, when I logged on our Blackboard CE8 SP2 and clicked on the Scholar link today, it worked. I immediately checked with my colleagues who helped in testing yesterday. They confirmed that it was also working for them. None of us encountered the above error any more.

It's good that it's working.

But I'm uncomfortable of not being able to understand was why it worked after we left the upgraded system overnight. Is it because some background job needed to run first so that the Scholar Powerlink would work after an upgrade? Mystery.

Thursday, July 31, 2008

SQL Mirroring Manual Failover for eLearning (Blackboard Learning System CE8)

In my previous SQL Mirroring for eLearning post, I listed the detail on how to setup SQL database mirroring for Blackboard Learning System CE8. Since the application (Weblogic) does not support automatic failover, we need to have a procedure and scripts ready to perform manual failover in the event of a diaster (when the production database server is no longer available).

Here is how:
  • Stop WebCT service on all frontend nodes.
  • If you use asynchronous mirroring, you can execute the following commands on the mirror (business continutiy) server to force failover. The databases will then be in "In Recovery" status. It will take a minute for it to change to "Principal, Disconnected" status. The Disconnected status means that there is no mirrored session going on for this new principal server which is correct.
ALTER DATABASE webctdatabase SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS

ALTER DATABASE webctdatabase$PF SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS
  • If you use synchronous mirroring instead, execute the following commands to failover:
ALTER DATABASE webctdatabase SET PARTNER FAILOVER

ALTER DATABASE webctdatabase$PF SET PARTNER FAILOVER
  • After failover, you need to execute the following in the new principal server to set the webct and webct$PF users' SID.
Use webctdatabase
go
sp_change_users_login 'report'

Use webctdatabase
go
sp_change_users_login 'update_one', 'webct', 'webct'

Use webctdatabase
go
sp_change_users_login 'update_one', 'webct$PF', 'webct$PF'


Use webctdatabase$PF
go
sp_change_users_login 'report'

Use webctdatabase$PF
go
sp_change_users_login 'update_one', 'webct', 'webct'

Use webctdatabase$PF
go
sp_change_users_login 'update_one', 'webct$PF', 'webct$PF'
  • Then you will need to change the jdbc connection string on the admin node and all managed nodes to point the database to the new principal server.
cd \bea92\weblogic92\config\WebCTDomain\config\jdbc\

copy /y CP-WebCTConnectionPool$PF-jdbc.xml CP-WebCTConnectionPool$PF-jdbc.before_db_migration.xml
copy /y CP-WebCTConnectionPool-jdbc.xml CP-WebCTConnectionPool-jdbc.before_db_migraton.xml
copy /y CP-WebCTJMSConnectionPool-jdbc.xml CP-WebCTJMSConnectionPool-jdbc.before_db_migration.xml

cat CP-WebCTConnectionPool$PF-jdbc.before_db_migration.xml | sed 's/ProdServer/BusContServer/' > CP-WebCTConnectionPool$PF-jdbc.xml
cat CP-WebCTConnectionPool-jdbc.before_db_migraton.xml | sed 's/ProdServer/BusContServer/' > CP-WebCTConnectionPool-jdbc.xml
cat CP-WebCTJMSConnectionPool-jdbc.before_db_migration.xml | sed 's/ProdServer/BusContServer/' > CP-WebCTJMSConnectionPool-jdbc.xml

diff CP-WebCTConnectionPool$PF-jdbc.before_db_migration.xml CP-WebCTConnectionPool$PF-jdbc.xml
diff CP-WebCTConnectionPool-jdbc.before_db_migraton.xml CP-WebCTConnectionPool-jdbc.xml
diff CP-WebCTJMSConnectionPool-jdbc.before_db_migration.xml CP-WebCTJMSConnectionPool-jdbc.xml
  • Bring up the Blackboard CE8 cluster.

SQL Mirroring for eLearning (Blackboard Learning System CE8)

We finally have a set of servers in another building designated for business continuity of our eLearning Learning Management System (powered by Blackboard Learning System CE8). We have a procedure to failover to that location in the event of a disaster. We even ran a contingency drill back in May to verify the process.

One of the outstanding problems we have is : eLearning's database is so hugh (and is getting larger every day) that in the event of a disaster, it takes a very long time to restore it from backup. In order to minimize the potential down time, we decided to use SQL database mirroring to mirror eLearning's database from our current production to the business continuity server.

Here is how:
  • Backup the eLearning's databases on the principal (production) server and restore them to the mirror (business continuity) server using the NORECOVERY option to ensure the log files on both servers match exactly.
restore database webctdatabase from DISK='D:\folder\webctdatabase.bak' WITH NORECOVERY, REPLACE

restore database webctdatabase$PF from DISK='D:\folder\webctdatabase$PF.bak' WITH NORECOVERY, REPLACE
  • On both the principal (production) and mirror (business continuity) servers, create database mirroring partner endpoint. (TCP port 5022 is used in this example since that the the default port number number. But that can be changed to any TCP port number available).
CREATE ENDPOINT mirroring_end_point
STATE=STARTED
AS TCP(LISTENER_PORT=5022)
FOR DATABASE_MIRRORING (ROLE=PARTNER)
  • On the mirror server, specify the principal server as the mirror partner.
ALTER DATABASE webctdatabase SET PARTNER = 'TCP://BusContServerName:5022'

ALTER DATABASE webctdatabase$PF SET PARTNER = 'TCP://BusContServerName:5022'
  • On the principal server, specify the mirror server as the mirror partner.
ALTER DATABASE webctdatabase SET PARTNER = 'TCP://ProdServerName:5022'

ALTER DATABASE webctdatabase$PF SET PARTNER = 'TCP://ProdServerName:5022'
  • Now the principal server will start sending transactions to the mirror server.
  • Initially, the principal server and the mirror server will be in a synchronizing state. After all transactions from the principal server have been reapplied on the mirror server, their states will change to synchronized.
By default, a mirror session operates in synchronous mode. But you may prefer the session to be asychronous instead due to performance reason (e.g. high latency between the principal and mirror server). You can execute the following command on either the principal or the mirror server to change the mirror session to asychronous mode.
ALTER DATABASE webctdatabase SET PARTNER SAFETY OFF

ALTER DATABASE webctdatabase$PF SET PARTNER SAFETY OFF
Also worth noting that one can set up a SQL server as a witness server for automatic failover. But the application has to support it. In our case, Blackboard CE8 does not. Therefore, we do not pursue this path. We have a procedure, and a script to perform manual failover instead.

Thursday, May 8, 2008

Visit from our Spokane Campus Colleagues about LMS Issues

Our colleagues in Spokane campus visited us to talk about the university learning management system. This is our presentation about the current state of eLearning (powered by Blackboard Learning System CE) which is used by the main Pullman campus.



They also maintain a learning Management system, which is powered by Blackboard Academic Suite, for the urban campuses and Distance Degree Program. Somewhere down the road, we are going to need to migrate, and merge into a single campus-wide solution. We compared notes, and exchanged ideas. It was good to start this conversation with the people who run a LMS day to day.

Friday, December 7, 2007

eLearning User Penetration Rate

I just created a script to determine the penetration rate of eLearning online Learning Management System (powered by Blackboard Learning System CE6, formly known as WebCT CE6) by comparing the enrollment data, Active Directory groups, with the actual logon users of the current semester.

For 2007 Fall semester, we have the following numbers in our main Pullman campus:

Undergraduate Students
Graduate Students
Undergraduate + Graduate Students
Total LMS
% Total LMS
% Total LMS %
15441 12862 83.30 1981 749 37.81 17422 13611 78.13

Saturday, July 21, 2007

BbWorld 07 Conference Presentation

Blackboard acquired WebCT in year 2006. There are a lot of changes made soon after the merger. The product WebCT Campus Edition was renamed to Blackboard Learning System CE. A number of senior engineers from WebCT left. The support model was changed. But the main issue is the lack of good and timely technical support, and this have caused us a lot of struggle to support the product day to day.

But our spirits remain strong. We, the same group who presented last year, met again and co-presented "A Year Later : Looking Back and Moving Forward" in the BbWorld '07 Conference. Here are the slides from our university:



Tuesday, August 1, 2006

WebCT Impact 2006 Conference Presentation

We are one of the first few universities who have migrated from WebCT CE4 to CE6/ Vista4 soonest as the product was released. Together, we presented "Lessons Learned : Migrating From CE4 To CE6/ Vista4" in the WebCT Impact 2006 Conference. Here are the slides from our university: